/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

#include "stdafx.h"
#include "FCChart.h"

namespace FaceCat{
    FCChart::FCChart() {
        m_autoFillHScale = false;
        m_allowDragChartDiv = false;
        m_candleDistance = 0;
        m_candleMax = 0;
        m_candleMin = 0;
        m_candleMaxRight = 0;
        m_candleMinRight = 0;
        m_crossTipColor = FCColor::rgb(50, 50, 50);
        m_crossLineColor = FCColor::rgb(100, 100, 100);
        m_candlePaddingTop = 30;
        m_candlePaddingBottom = 30;
        m_candleDigit = 2;
        m_candleDivPercent = 0.5;
        m_crossStopIndex = -1;
        m_cycle = L"second";
        m_downColor = FCColor::rgb(15, 193, 118);
        m_firstVisibleIndex = -1;
        m_gridColor = FCColor::rgba(255, 0, 0, 120);
        m_lastVisibleIndex = -1;
        m_leftVScaleWidth = 80;
        m_lastRecordIsVisible = true;
        m_lastVisibleKey = 0;
        m_hScalePixel = 11;
        m_hScaleHeight = 30;
        m_hScaleTextDistance = 10;
        m_indMax = 0;
        m_indMin = 0;
        m_indMax2 = 0;
        m_indMin2 = 0;
        m_indMaxRight = 0;
        m_indMinRight = 0;
        m_indMax2Right = 0;
        m_indMin2Right = 0;
        m_indDigit = 2;
        m_indDigit2 = 2;
        m_indDivPercent = 0.3;
        m_indDivPercent2 = 0.0;
        m_indPaddingTop = 20;
        m_indPaddingBottom = 20;
        m_indPaddingTop2 = 20;
        m_indPaddingBottom2 = 20;
        m_lastValidIndex = -1;
        m_lineWidthChart = 1;
        m_magnitude = 1;
        m_midColor = FCColor_None;
        m_offsetX = 0;
        m_plotPointSizeChart = 20;
        m_rightVScaleWidth = 0;
        m_rightSpace = 0;
        m_scaleColor = FCColor::rgb(255, 0, 0);
        m_showCrossLine = true;
        m_selectPlotPoint = -1;
        m_startMovePlot = false;
        m_sPlot = 0;
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        m_volMax = 0;
        m_volMin = 0;
        m_volMaxRight = 0;
        m_volMinRight = 0;
        m_volDigit = 0;
        m_volDivPercent = 0.2;
        m_volPaddingTop = 20;
        m_volPaddingBottom = 0;
        m_vScaleDistance = 35;
        m_vScaleType = L"standard";
        m_upColor = FCColor::rgb(219, 68, 83);
        m_kChart = 0;
        m_bChart = 0;
        m_oXChart = 0;
        m_oYChart = 0;
        m_rChart = 0;
        m_gridStepChart = 0;
        m_gridDigitChart = 0;
        m_firstIndexCacheChart = -1;
        m_firstTouchIndexCacheChart = -1;
        m_lastIndexCacheChart = -1;
        m_secondTouchIndexCacheChart = -1;
        m_firstPaddingTop = 0;
        m_firtstPaddingBottom = 0;
        m_x4Chart = 0;
        m_y4Chart = 0;
        m_nHighChart = 0;
        m_nLowChart = 0;
        m_xChart = 0;
        m_yChart = 0;
        m_wChart = 0;
        m_hChart = 0;
        m_upSubValue = 0;
        m_downSubValue = 0;
        m_indicatorColors.add(FCColor::rgb(100, 100, 100));
        m_indicatorColors.add(FCColor::rgb(206, 147, 27));
        m_indicatorColors.add(FCColor::rgb(150, 0, 150));
        m_indicatorColors.add(FCColor::rgb(255, 0, 0));
        m_indicatorColors.add(FCColor::rgb(0, 150, 150));
        m_indicatorColors.add(FCColor::rgb(0, 150, 0));
        m_indicatorColors.add(FCColor::rgb(59, 174, 218));
        m_indicatorColors.add(FCColor::rgb(50, 50, 50));
        m_candleStyle = L"rect";
        m_barStyle = L"rect";
        m_firstOpen = 0;
    }

    FCChart::~FCChart() {
        m_data.clear();
        for (int i = 0; i < m_plots.size(); i++) {
            delete m_plots.get(i);
        }
        m_plots.clear();
        for (int i = 0; i < m_shapes.size(); i++) {
            delete m_shapes.get(i);
        }
        m_shapes.clear();
        m_sPlot = 0; //选中的线条
        m_allema12.clear();
        m_allema26.clear();
        m_alldifarr.clear();
        m_alldeaarr.clear();
        m_allmacdarr.clear();
        m_bollUp.clear();
        m_bollDown.clear();
        m_bollMid.clear();
        m_bias1.clear();
        m_bias2.clear();
        m_bias3.clear();
        m_kdjK.clear();
        m_kdjD.clear();
        m_kdjJ.clear();
        m_rsi1.clear();
        m_rsi2.clear();
        m_rsi3.clear();
        m_roc.clear();
        m_rocMa.clear();
        m_wr1.clear();
        m_wr2.clear();
        m_cci.clear();
        m_bbi.clear();
        m_trix.clear();
        m_trixMa.clear();
        m_dma1.clear();
        m_dma2.clear();
        m_ma5.clear();
        m_ma10.clear();
        m_ma20.clear();
        m_ma30.clear();
        m_ma120.clear();
        m_ma250.clear();
        m_closeArr.clear();
    }

    void FCChart::addPlotDefault(bool firstTouch, const FCPoint& firstPoint, bool secondTouch, const FCPoint& secondPoint, const String& darkOrLight) {
        FCPoint mp = firstPoint;
        if (mp.y < getCandleDivHeight())
        {
            int touchIndex = getChartIndex(mp);
            if (touchIndex >= m_firstVisibleIndex &&
                touchIndex <= m_lastVisibleIndex)
            {
                if (m_addingPlotChart == L"FiboTimezone")
                {
                    int fIndex = touchIndex;
                    double fDate = getChartDateByIndex(fIndex);
                    double y = getChartValue(mp);
                    FCPlot *newPlot = new FCPlot();
                    if (darkOrLight == L"light")
                    {
                        newPlot->m_lineColor = FCColor::rgb(0, 0, 0);
                        newPlot->m_pointColor = FCColor::rgba(0, 0, 0, 125);
                    }
                    else
                    {
                        newPlot->m_lineColor = FCColor::rgb(255, 255, 255);
                        newPlot->m_pointColor = FCColor::rgba(255, 255, 255, 125);
                    }
                    newPlot->m_key1 = fDate;
                    newPlot->m_value1 = y;
                    newPlot->m_plotType = m_addingPlotChart;
                    m_plots.add(newPlot);
                    m_sPlot = 0;
                    FCPlot *selectedPlot = selectPlot(mp);
                    if (selectedPlot)
                    {
                        m_sPlot = selectedPlot;
                    }
                }
                else if (m_addingPlotChart == L"Triangle" ||
                    m_addingPlotChart == L"CircumCycle" ||
                    m_addingPlotChart == L"ParalleGram" ||
                    m_addingPlotChart == L"AngleLine" ||
                    m_addingPlotChart == L"Parallel" ||
                    m_addingPlotChart == L"SymmetricTriangle")
                {
                    int eIndex = touchIndex;
                    int bIndex = eIndex - 5;
                    if (bIndex >= 0)
                    {
                        double fDate = getChartDateByIndex(bIndex);
                        double sDate = getChartDateByIndex(eIndex);
                        double y = getChartValue(mp);
                        FCPlot *newPlot = new FCPlot();
                        if (darkOrLight == L"light")
                        {
                            newPlot->m_lineColor = FCColor::rgb(0, 0, 0);
                            newPlot->m_pointColor = FCColor::rgba(0, 0, 0, 125);
                        }
                        else
                        {
                            newPlot->m_lineColor = FCColor::rgb(255, 255, 255);
                            newPlot->m_pointColor = FCColor::rgba(255, 255, 255, 125);
                        }
                        newPlot->m_key1 = fDate;
                        newPlot->m_value1 = y;
                        newPlot->m_key2 = sDate;
                        newPlot->m_value2 = y;
                        newPlot->m_key3 = sDate;
                        newPlot->m_value3 =
                            m_candleMin + (m_candleMax - m_candleMin) / 2;
                        newPlot->m_plotType = m_addingPlotChart;
                        m_plots.add(newPlot);
                        m_sPlot = 0;
                        FCPlot *selectedPlot = selectPlot(mp);
                        if (selectedPlot)
                        {
                            m_sPlot = selectedPlot;
                        }
                    }
                }
                else
                {
                    int eIndex = touchIndex;
                    int bIndex = eIndex - 5;
                    if (bIndex >= 0)
                    {
                        double fDate = getChartDateByIndex(bIndex);
                        double sDate = getChartDateByIndex(eIndex);
                        double y = getChartValue(mp);
                        FCPlot *newPlot = new FCPlot();
                        if (darkOrLight == L"light")
                        {
                            newPlot->m_lineColor = FCColor::rgb(0, 0, 0);
                            newPlot->m_pointColor = FCColor::rgba(0, 0, 0, 125);
                        }
                        else
                        {
                            newPlot->m_lineColor = FCColor::rgb(255, 255, 255);
                            newPlot->m_pointColor = FCColor::rgba(255, 255, 255, 125);
                        }
                        newPlot->m_key1 = fDate;
                        newPlot->m_value1 = y;
                        newPlot->m_key2 = sDate;
                        newPlot->m_value2 = y;
                        newPlot->m_plotType = m_addingPlotChart;
                        m_plots.add(newPlot);
                        m_sPlot = 0;
                        FCPlot *selectedPlot = selectPlot(mp);
                        if (selectedPlot)
                        {
                            m_sPlot = selectedPlot;
                        }
                    }
                }
            }
        }
    }

    double FCChart::avgValue(ArrayList<double>* list) {
        double sum = 0;
        int length = list->size();
        if (length > 0)
        {
            for (int i = 0; i < length; i++)
            {
                sum += list->get(i);
            }
            return sum / length;
        }
        return 0;
    }

    double FCChart::chartGridScale(double min, double max, int yLen, double maxSpan, double minSpan, int defCount) {
        double sub = max - min;
        int nMinCount = (int)ceil(yLen / maxSpan);
        int nMaxCount = (int)floor(yLen / minSpan);
        int nCount = defCount;
        double logStep = sub / nCount;
        bool start = false;
        double divisor = 0;
        int i = 0, nTemp = 0;
        m_gridStepChart = 0;
        m_gridDigitChart = 0;
        nCount = nMinCount > nCount ? nMinCount : nCount;
        nCount = nMaxCount > nCount ? nCount : nMaxCount;
        nCount = nCount > 1 ? nCount : 1;
        for (i = 15; i >= -6; i--)
        {
            divisor = pow(10.0, (double)i);
            if (divisor < 1)
            {
                m_gridDigitChart++;
            }
            nTemp = (int)floor(logStep / divisor);
            if (start)
            {
                if (nTemp < 4)
                {
                    if (m_gridDigitChart > 0)
                    {
                        m_gridDigitChart--;
                    }
                }
                else if (nTemp >= 4 && nTemp <= 6)
                {
                    nTemp = 5;
                    m_gridStepChart += nTemp * divisor;
                }
                else
                {
                    m_gridStepChart += 10 * divisor;
                    if (m_gridDigitChart > 0)
                    {
                        m_gridDigitChart--;
                    }
                }
                break;
            }
            else if (nTemp > 0)
            {
                m_gridStepChart = nTemp * divisor + m_gridStepChart;
                logStep -= m_gridStepChart;
                start = true;
            }
        }
        return 0;
    }

    void FCChart::calculateChartMaxMin() {
        m_candleMax = 0;
        m_candleMin = 0;
        m_volMax = 0;
        m_volMin = 0;
        m_indMin = 0;
        m_indMin = 0;
        bool load1 = false;
        bool load2 = false;
        bool load3 = false;
        bool load4 = false;
        bool isTrend = m_cycle == L"trend";
        double firstOpen = m_firstOpen;
        if (m_data.size() > 0)
        {
            int lastValidIndex = m_lastVisibleIndex;
            if (m_lastValidIndex != -1)
            {
                lastValidIndex = m_lastValidIndex;
            }
            for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
            {
                if (i == m_firstVisibleIndex)
                {
                    if (isTrend)
                    {
                        m_candleMax = m_data.get(i).m_close;
                        m_candleMin = m_data.get(i).m_close;
                        if(firstOpen == 0){
                            firstOpen = m_data.get(i).m_close;
                        }
                    }
                    else
                    {
                        m_candleMax = m_data.get(i).m_high;
                        m_candleMin = m_data.get(i).m_low;
                    }
                    m_volMax = m_data.get(i).m_volume;
                    load1 = true;
                    load2 = true;
                    if (m_showIndicator == L"MACD")
                    {
                        m_indMax = m_alldifarr.get(i);
                        m_indMin = m_alldifarr.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"KDJ")
                    {
                        m_indMax = m_kdjK.get(i);
                        m_indMin = m_kdjK.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"RSI")
                    {
                        m_indMax = m_rsi1.get(i);
                        m_indMin = m_rsi1.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"BIAS")
                    {
                        m_indMax = m_bias1.get(i);
                        m_indMin = m_bias1.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"ROC")
                    {
                        m_indMax = m_roc.get(i);
                        m_indMin = m_roc.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"WR")
                    {
                        m_indMax = m_wr1.get(i);
                        m_indMin = m_wr1.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"CCI")
                    {
                        m_indMax = m_cci.get(i);
                        m_indMin = m_cci.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"BBI")
                    {
                        m_indMax = m_bbi.get(i);
                        m_indMin = m_bbi.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"TRIX")
                    {
                        m_indMax = m_trix.get(i);
                        m_indMin = m_trix.get(i);
                        load3 = true;
                    }
                    else if (m_showIndicator == L"DMA")
                    {
                        m_indMax = m_dma1.get(i);
                        m_indMin = m_dma1.get(i);
                        load3 = true;
                    }
                }
                else
                {
                    if (isTrend)
                    {
                        if (m_candleMax < m_data.get(i).m_close)
                        {
                            m_candleMax = m_data.get(i).m_close;
                        }
                        if (m_candleMin > m_data.get(i).m_close)
                        {
                            m_candleMin = m_data.get(i).m_close;
                        }
                    }
                    else
                    {
                        if (m_candleMax < m_data.get(i).m_high)
                        {
                            m_candleMax = m_data.get(i).m_high;
                        }
                        if (m_candleMin > m_data.get(i).m_low)
                        {
                            m_candleMin = m_data.get(i).m_low;
                        }
                    }
                    if (m_volMax < m_data.get(i).m_volume)
                    {
                        m_volMax = m_data.get(i).m_volume;
                    }
                }
                if (m_showIndicator == L"MACD")
                {
                    if (m_indMax < m_alldifarr.get(i))
                    {
                        m_indMax = m_alldifarr.get(i);
                    }
                    if (m_indMax < m_alldeaarr.get(i))
                    {
                        m_indMax = m_alldeaarr.get(i);
                    }
                    if (m_indMax < m_allmacdarr.get(i))
                    {
                        m_indMax = m_allmacdarr.get(i);
                    }
                    if (m_indMin > m_alldifarr.get(i))
                    {
                        m_indMin = m_alldifarr.get(i);
                    }
                    if (m_indMin > m_alldeaarr.get(i))
                    {
                        m_indMin = m_alldeaarr.get(i);
                    }
                    if (m_indMin > m_allmacdarr.get(i))
                    {
                        m_indMin = m_allmacdarr.get(i);
                    }
                }
                else if (m_showIndicator == L"KDJ")
                {
                    if (m_indMax < m_kdjK.get(i))
                    {
                        m_indMax = m_kdjK.get(i);
                    }
                    if (m_indMax < m_kdjD.get(i))
                    {
                        m_indMax = m_kdjD.get(i);
                    }
                    if (m_indMax < m_kdjJ.get(i))
                    {
                        m_indMax = m_kdjJ.get(i);
                    }
                    if (m_indMin > m_kdjK.get(i))
                    {
                        m_indMin = m_kdjK.get(i);
                    }
                    if (m_indMin > m_kdjD.get(i))
                    {
                        m_indMin = m_kdjD.get(i);
                    }
                    if (m_indMin > m_kdjJ.get(i))
                    {
                        m_indMin = m_kdjJ.get(i);
                    }
                }
                else if (m_showIndicator == L"RSI")
                {
                    if (m_indMax < m_rsi1.get(i))
                    {
                        m_indMax = m_rsi1.get(i);
                    }
                    if (m_indMax < m_rsi2.get(i))
                    {
                        m_indMax = m_rsi2.get(i);
                    }
                    if (m_indMax < m_rsi3.get(i))
                    {
                        m_indMax = m_rsi3.get(i);
                    }
                    if (m_indMin > m_rsi1.get(i))
                    {
                        m_indMin = m_rsi1.get(i);
                    }
                    if (m_indMin > m_rsi2.get(i))
                    {
                        m_indMin = m_rsi2.get(i);
                    }
                    if (m_indMin > m_rsi3.get(i))
                    {
                        m_indMin = m_rsi3.get(i);
                    }
                }
                else if (m_showIndicator == L"BIAS")
                {
                    if (m_indMax < m_bias1.get(i))
                    {
                        m_indMax = m_bias1.get(i);
                    }
                    if (m_indMax < m_bias2.get(i))
                    {
                        m_indMax = m_bias2.get(i);
                    }
                    if (m_indMax < m_bias3.get(i))
                    {
                        m_indMax = m_bias3.get(i);
                    }
                    if (m_indMin > m_bias1.get(i))
                    {
                        m_indMin = m_bias1.get(i);
                    }
                    if (m_indMin > m_bias2.get(i))
                    {
                        m_indMin = m_bias2.get(i);
                    }
                    if (m_indMin > m_bias3.get(i))
                    {
                        m_indMin = m_bias3.get(i);
                    }
                }
                else if (m_showIndicator == L"ROC")
                {
                    if (m_indMax < m_roc.get(i))
                    {
                        m_indMax = m_roc.get(i);
                    }
                    if (m_indMax < m_rocMa.get(i))
                    {
                        m_indMax = m_rocMa.get(i);
                    }
                    if (m_indMin > m_roc.get(i))
                    {
                        m_indMin = m_roc.get(i);
                    }
                    if (m_indMin > m_rocMa.get(i))
                    {
                        m_indMin = m_rocMa.get(i);
                    }
                }
                else if (m_showIndicator == L"WR")
                {
                    if (m_indMax < m_wr1.get(i))
                    {
                        m_indMax = m_wr1.get(i);
                    }
                    if (m_indMax < m_wr2.get(i))
                    {
                        m_indMax = m_wr2.get(i);
                    }
                    if (m_indMin > m_wr1.get(i))
                    {
                        m_indMin = m_wr1.get(i);
                    }
                    if (m_indMin > m_wr2.get(i))
                    {
                        m_indMin = m_wr2.get(i);
                    }
                }
                else if (m_showIndicator == L"CCI")
                {
                    if (m_indMax < m_cci.get(i))
                    {
                        m_indMax = m_cci.get(i);
                    }
                    if (m_indMin > m_cci.get(i))
                    {
                        m_indMin = m_cci.get(i);
                    }
                }
                else if (m_showIndicator == L"BBI")
                {
                    if (m_indMax < m_bbi.get(i))
                    {
                        m_indMax = m_bbi.get(i);
                    }
                    if (m_indMin > m_bbi.get(i))
                    {
                        m_indMin = m_bbi.get(i);
                    }
                }
                else if (m_showIndicator == L"TRIX")
                {
                    if (m_indMax < m_trix.get(i))
                    {
                        m_indMax = m_trix.get(i);
                    }
                    if (m_indMax < m_trixMa.get(i))
                    {
                        m_indMax = m_trixMa.get(i);
                    }
                    if (m_indMin > m_trix.get(i))
                    {
                        m_indMin = m_trix.get(i);
                    }
                    if (m_indMin > m_trixMa.get(i))
                    {
                        m_indMin = m_trixMa.get(i);
                    }
                }
                else if (m_showIndicator == L"DMA")
                {
                    if (m_indMax < m_dma1.get(i))
                    {
                        m_indMax = m_dma1.get(i);
                    }
                    if (m_indMax < m_dma2.get(i))
                    {
                        m_indMax = m_dma2.get(i);
                    }
                    if (m_indMin > m_dma1.get(i))
                    {
                        m_indMin = m_dma1.get(i);
                    }
                    if (m_indMin > m_dma2.get(i))
                    {
                        m_indMin = m_dma2.get(i);
                    }
                }
            }
        }
        if (m_shapes.size() > 0)
        {
            int lastValidIndex = m_lastVisibleIndex;
            if (m_lastValidIndex != -1)
            {
                lastValidIndex = m_lastValidIndex;
            }
            for (int s = 0; s < m_shapes.size(); s++)
            {
                BaseShape *shape = m_shapes.get(s);
                if (shape->m_datas.size() > 0)
                {
                    for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                    {
                        if (shape->m_divIndex == 0)
                        {
                            if (!load1 && i == m_firstVisibleIndex)
                            {
                                if (shape->m_leftOrRight)
                                {
                                    m_candleMax = shape->m_datas.get(i);
                                    m_candleMin = shape->m_datas.get(i);
                                }
                                else
                                {
                                    m_candleMaxRight = shape->m_datas.get(i);
                                    m_candleMinRight = shape->m_datas.get(i);
                                }
                                load1 = true;
                            }
                            else
                            {
                                if (shape->m_leftOrRight)
                                {
                                    if (shape->m_datas.get(i) > m_candleMax)
                                    {
                                        m_candleMax = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_candleMin)
                                    {
                                        m_candleMin = shape->m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape->m_datas.get(i) > m_candleMaxRight)
                                    {
                                        m_candleMaxRight = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_candleMinRight)
                                    {
                                        m_candleMinRight = shape->m_datas.get(i);
                                    }
                                }
                            }
                        }
                        else if (shape->m_divIndex == 1)
                        {
                            if (!load2 && i == m_firstVisibleIndex)
                            {
                                if (shape->m_leftOrRight)
                                {
                                    m_volMax = shape->m_datas.get(i);
                                    m_volMin = shape->m_datas.get(i);
                                }
                                else
                                {
                                    m_volMaxRight = shape->m_datas.get(i);
                                    m_volMinRight = shape->m_datas.get(i);
                                }
                                load2 = true;
                            }
                            else
                            {
                                if (shape->m_leftOrRight)
                                {
                                    if (shape->m_datas.get(i) > m_volMax)
                                    {
                                        m_volMax = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_volMin)
                                    {
                                        m_volMin = shape->m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape->m_datas.get(i) > m_volMaxRight)
                                    {
                                        m_volMaxRight = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_volMinRight)
                                    {
                                        m_volMinRight = shape->m_datas.get(i);
                                    }
                                }
                            }
                        }
                        else if (shape->m_divIndex == 2)
                        {
                            if (!load3 && i == m_firstVisibleIndex)
                            {
                                if (shape->m_leftOrRight)
                                {
                                    m_indMax = shape->m_datas.get(i);
                                    m_indMin = shape->m_datas.get(i);
                                }
                                else
                                {
                                    m_indMaxRight = shape->m_datas.get(i);
                                    m_indMinRight = shape->m_datas.get(i);
                                }
                                load3 = true;
                            }
                            else
                            {
                                if (shape->m_leftOrRight)
                                {
                                    if (shape->m_datas.get(i) > m_indMax)
                                    {
                                        m_indMax = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_indMin)
                                    {
                                        m_indMin = shape->m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape->m_datas.get(i) > m_indMaxRight)
                                    {
                                        m_indMaxRight = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_indMinRight)
                                    {
                                        m_indMinRight = shape->m_datas.get(i);
                                    }
                                }
                            }
                        }
                        else if (shape->m_divIndex == 3)
                        {
                            if (!load4 && i == m_firstVisibleIndex)
                            {
                                if (shape->m_leftOrRight)
                                {
                                    m_indMax2 = shape->m_datas.get(i);
                                    m_indMin2 = shape->m_datas.get(i);
                                }
                                else
                                {
                                    m_indMax2Right = shape->m_datas.get(i);
                                    m_indMin2Right = shape->m_datas.get(i);
                                }
                                load4 = true;
                            }
                            else
                            {
                                if (shape->m_leftOrRight)
                                {
                                    if (shape->m_datas.get(i) > m_indMax2)
                                    {
                                        m_indMax2 = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_indMin2)
                                    {
                                        m_indMin2 = shape->m_datas.get(i);
                                    }
                                }
                                else
                                {
                                    if (shape->m_datas.get(i) > m_indMax2Right)
                                    {
                                        m_indMax2Right = shape->m_datas.get(i);
                                    }
                                    if (shape->m_datas.get(i) < m_indMin2Right)
                                    {
                                        m_indMin2Right = shape->m_datas.get(i);
                                    }
                                }
                            }
                        }
                    }
                }
                if (shape->m_datas2.size() > 0)
                {
                    for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                    {
                        if (shape->m_divIndex == 0)
                        {
                            if (shape->m_leftOrRight)
                            {
                                if (shape->m_datas2.get(i) > m_candleMax)
                                {
                                    m_candleMax = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_candleMin)
                                {
                                    m_candleMin = shape->m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape->m_datas2.get(i) > m_candleMaxRight)
                                {
                                    m_candleMaxRight = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_candleMinRight)
                                {
                                    m_candleMinRight = shape->m_datas2.get(i);
                                }
                            }
                        }
                        else if (shape->m_divIndex == 1)
                        {
                            if (shape->m_leftOrRight)
                            {
                                if (shape->m_datas2.get(i) > m_volMax)
                                {
                                    m_volMax = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_volMin)
                                {
                                    m_volMin = shape->m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape->m_datas2.get(i) > m_volMaxRight)
                                {
                                    m_volMaxRight = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_volMinRight)
                                {
                                    m_volMinRight = shape->m_datas2.get(i);
                                }
                            }
                        }
                        else if (shape->m_divIndex == 2)
                        {
                            if (shape->m_leftOrRight)
                            {
                                if (shape->m_datas2.get(i) > m_indMax)
                                {
                                    m_indMax = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_indMin)
                                {
                                    m_indMin = shape->m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape->m_datas2.get(i) > m_indMaxRight)
                                {
                                    m_indMaxRight = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_indMinRight)
                                {
                                    m_indMinRight = shape->m_datas2.get(i);
                                }
                            }
                        }
                        else if (shape->m_divIndex == 3)
                        {
                            if (shape->m_leftOrRight)
                            {
                                if (shape->m_datas2.get(i) > m_indMax2)
                                {
                                    m_indMax2 = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_indMin2)
                                {
                                    m_indMin2 = shape->m_datas2.get(i);
                                }
                            }
                            else
                            {
                                if (shape->m_datas2.get(i) > m_indMax2Right)
                                {
                                    m_indMax2Right = shape->m_datas2.get(i);
                                }
                                if (shape->m_datas2.get(i) < m_indMin2Right)
                                {
                                    m_indMin2Right = shape->m_datas2.get(i);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (isTrend)
        {
            double abs1 = m_candleMax - firstOpen > 0 ? m_candleMax - firstOpen : firstOpen - m_candleMax;
            double abs2 = m_candleMin - firstOpen > 0 ? m_candleMin - firstOpen : firstOpen - m_candleMin;
            double subMax = abs1 > abs2 ? abs1 : abs2;
            m_candleMax = firstOpen + subMax;
            m_candleMin = firstOpen - subMax;
        }
        else
        {
            if (m_candleMax == 0 && m_candleMin == 0)
            {
                m_candleMax = 1;
                m_candleMin = -1;
            }
            if (m_volMax == 0 && m_volMin == 0)
            {
                m_volMax = 1;
                m_volMin = -1;
            }
            if (m_indMax == 0 && m_indMin == 0)
            {
                m_indMax = 1;
                m_indMin = -1;
            }
            if (m_indMax2 == 0 && m_indMin2 == 0)
            {
                m_indMax2 = 1;
                m_indMin2 = -1;
            }
            if (m_candleMaxRight == 0 && m_candleMinRight == 0)
            {
                m_candleMaxRight = 1;
                m_candleMinRight = -1;
            }
            if (m_volMaxRight == 0 && m_volMinRight == 0)
            {
                m_volMaxRight = 1;
                m_volMinRight = -1;
            }
            if (m_indMaxRight == 0 && m_indMinRight == 0)
            {
                m_indMaxRight = 1;
                m_indMinRight = -1;
            }
            if (m_indMax2Right == 0 && m_indMin2Right == 0)
            {
                m_indMax2Right = 1;
                m_indMin2Right = -1;
            }
        }
    }

    void FCChart::checkChartLastVisibleIndex() {
        int dataCount = m_data.size();
        int workingAreaWidth = getChartWorkAreaWidth();
        int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, workingAreaWidth);
        if (m_firstVisibleIndex < 0)
        {
            m_firstVisibleIndex = 0;
        }
        if (m_lastVisibleIndex >= m_firstVisibleIndex + maxVisibleRecord - 1 || m_lastVisibleIndex < dataCount - 1)
        {
            m_lastVisibleIndex = m_firstVisibleIndex + maxVisibleRecord - 1;
        }
        if (m_lastVisibleIndex > dataCount - 1)
        {
            m_lastVisibleIndex = dataCount - 1;
        }
        if (m_data.size() > 0 && m_lastVisibleIndex != -1)
        {
            m_lastVisibleKey = m_data.get(m_lastVisibleIndex).m_date;
            if (m_lastVisibleIndex == m_data.size() - 1)
            {
                m_lastRecordIsVisible = true;
            }
            else
            {
                m_lastRecordIsVisible = false;
            }
        }
        else
        {
            m_lastVisibleKey = 0;
            m_lastRecordIsVisible = true;
        }
    }

    void FCChart::clearDataArr() {
        m_allema12.clear();
        m_allema26.clear();
        m_alldifarr.clear();
        m_alldeaarr.clear();
        m_allmacdarr.clear();
        m_bollUp.clear();
        m_bollDown.clear();
        m_bollMid.clear();
        m_bias1.clear();
        m_bias2.clear();
        m_bias3.clear();
        m_kdjK.clear();
        m_kdjD.clear();
        m_kdjJ.clear();
        m_rsi1.clear();
        m_rsi2.clear();
        m_rsi3.clear();
        m_roc.clear();
        m_rocMa.clear();
        m_wr1.clear();
        m_wr2.clear();
        m_cci.clear();
        m_bbi.clear();
        m_trix.clear();
        m_trixMa.clear();
        m_dma1.clear();
        m_dma2.clear();
        m_ma5.clear();
        m_ma10.clear();
        m_ma20.clear();
        m_ma30.clear();
        m_ma120.clear();
        m_ma250.clear();
    }

    void FCChart::calcChartIndicator() {
        clearDataArr();
        ArrayList<double> closeArr;
        ArrayList<double> highArr;
        ArrayList<double> lowArr;
        if (m_data.size() > 0)
        {
            for (int i = 0; i < m_data.size(); i++)
            {
                closeArr.add(m_data.get(i).m_close);
                highArr.add(m_data.get(i).m_high);
                lowArr.add(m_data.get(i).m_low);
            }
        }
        m_closeArr = closeArr;
        if (m_mainIndicator == L"BOLL")
        {
            getBollData(&closeArr, 20, &m_bollUp, &m_bollMid, &m_bollDown);
        }
        else if (m_mainIndicator == L"MA")
        {
            m_ma5 = maValue(&closeArr, 5);
            m_ma10 = maValue(&closeArr, 10);
            m_ma20 = maValue(&closeArr, 20);
            m_ma30 = maValue(&closeArr, 30);
            m_ma120 = maValue(&closeArr, 120);
            m_ma250 = maValue(&closeArr, 250);
        }
        if (m_showIndicator == L"BIAS")
        {
            getBIASData(&closeArr, 6, 12, 24, &m_bias1, &m_bias2, &m_bias3);
        }
        else if (m_showIndicator == L"DMA")
        {
            getDMAData(&closeArr, 10, 50, &m_dma1, &m_dma2);
        }
        else if (m_showIndicator == L"BBI")
        {
            getBBIData(&closeArr, 3, 6, 12, 24, &m_bbi);
        }
        else if (m_showIndicator == L"RSI")
        {
            getRSIData(&closeArr, 6, 12, 24, &m_rsi1, &m_rsi2, &m_rsi3);
        }
        else if (m_showIndicator == L"ROC")
        {
            getRocData(&closeArr, 12, 6, &m_roc, &m_rocMa);
        }
        else if (m_showIndicator == L"TRIX")
        {
            getTRIXData(&closeArr, 9, &m_trix, &m_trixMa);
        }
        else if (m_showIndicator == L"KDJ")
        {
            getKDJData(
                &highArr, &lowArr, &closeArr, 9, 3, 3, &m_kdjK, &m_kdjD, &m_kdjJ);
        }
        else if (m_showIndicator == L"WR")
        {
            getWRData(&highArr, &lowArr, &closeArr, 5, 10, &m_wr1, &m_wr2);
        }
        else if (m_showIndicator == L"CCI")
        {
            getCCIData(&highArr, &lowArr, &closeArr, 14, &m_cci);
        }
        else if (m_showIndicator == L"MACD")
        {
            //缓存MACD数据
            m_allema12.add(closeArr.get(0));
            m_allema26.add(closeArr.get(0));
            m_alldeaarr.add(0);
            for (int i = 1; i < closeArr.size(); i++)
            {
                m_allema12.add(getEMA(12, closeArr.get(i), m_allema12.get(i - 1)));
                m_allema26.add(getEMA(26, closeArr.get(i), m_allema26.get(i - 1)));
            }
            m_alldifarr = getDIF(&m_allema12, &m_allema26);
            for (int i = 1; i < m_alldifarr.size(); i++)
            {
                m_alldeaarr
                    .add(m_alldeaarr.get(i - 1) * 8 / 10 + m_alldifarr.get(i) * 2 / 10);
            }
            m_allmacdarr = getMACD(&m_alldifarr, &m_alldeaarr);
        }
        calculateChartMaxMin();
    }

    void FCChart::drawChartLines(FCPaint* paint, const FCRect& clipRect, int divIndex, ArrayList<double>* datas, Long color, bool selected) {
        ArrayList<FCPoint> drawPoints;
        int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
        int lastValidIndex = m_lastVisibleIndex;
        if (m_lastValidIndex != -1)
        {
            lastValidIndex = m_lastValidIndex;
        }
        for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
        {
            int x = getChartX(i);
            double value = datas->get(i);
            int y = getChartY(divIndex, value);
            FCPoint point = { x, y };
            drawPoints.add(point);
            if (selected)
            {
                int kPInterval = maxVisibleRecord / 30;
                if (kPInterval < 2)
                {
                    kPInterval = 3;
                }
                if (i % kPInterval == 0)
                {
                    paint->fillRect(color, (int)(x - 3), (int)(y - 3), (int)(x + 3), (int)(y + 3));
                }
            }
        }
        FCPoint* apt = new FCPoint[drawPoints.size()];
        for (int i = 0; i < drawPoints.size(); i++) {
            apt[i] = drawPoints.get(i);
        }
        paint->drawPolyline(color, (float)m_lineWidthChart, 0, apt, drawPoints.size());
        delete[] apt;
        apt = 0;
    }

    void FCChart::drawChartLinesInRight(FCPaint* paint, const FCRect& clipRect, int divIndex, ArrayList<double>* datas, Long color, bool selected) {
        ArrayList<FCPoint> drawPoints;
        int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
        int lastValidIndex = m_lastVisibleIndex;
        if (m_lastValidIndex != -1)
        {
            lastValidIndex = m_lastValidIndex;
        }
        for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
        {
            int x = getChartX(i);
            double value = datas->get(i);
            int y = getChartYInRight(divIndex, value);
            FCPoint point = { x, y };
            drawPoints.add(point);
            if (selected)
            {
                int kPInterval = maxVisibleRecord / 30;
                if (kPInterval < 2)
                {
                    kPInterval = 3;
                }
                if (i % kPInterval == 0)
                {
                    paint->fillRect(color, (int)(x - 3), (int)(y - 3), (int)(x + 3), (int)(y + 3));
                }
            }
        }
        FCPoint* apt = new FCPoint[drawPoints.size()];
        for (int i = 0; i < drawPoints.size(); i++) {
            apt[i] = drawPoints.get(i);
        }
        paint->drawPolyline(color, (float)m_lineWidthChart, 0, apt, drawPoints.size());
        delete[] apt;
        apt = 0;
    }

    void FCChart::drawChartPlot(FCPaint* paint, const FCRect& clipRect) {
        FCSize size = getSize();
        int divHeight = getCandleDivHeight();
        FCRect cRect = { m_leftVScaleWidth > clipRect.left ? m_leftVScaleWidth : clipRect.left, 0 > clipRect.top ? 0 : clipRect.top, size.cx - m_rightVScaleWidth < clipRect.bottom ? size.cx - m_rightVScaleWidth : clipRect.right , divHeight < clipRect.bottom ? divHeight : clipRect.bottom };
        paint->setClip(cRect);
        for (int i = 0; i < m_plots.size(); i++)
        {
            FCPlot *plot = m_plots.get(i);
            int index1 = 0, index2 = 0, index3 = 0;
            int mpx1 = 0, mpy1 = 0, mpx2 = 0, mpy2 = 0, mpx3 = 0, mpy3 = 0;
            if (plot->m_plotType == L"LRLine" ||
                plot->m_plotType == L"LRChannel" ||
                plot->m_plotType == L"LRBand")
            {
                ArrayList<double> list;
                index1 = getChartIndexByDate(plot->m_key1);
                index2 = getChartIndexByDate(plot->m_key2);
                int minIndex = index1 > index2 ? index2 : index1;
                int maxIndex = index1 > index2 ? index1 : index2;
                for (int j = minIndex; j <= maxIndex; j++)
                {
                    list.add(m_data.get(j).m_close);
                }
                linearRegressionEquation(&list);
                plot->m_value1 = m_bChart;
                plot->m_value2 = m_kChart * (maxIndex - minIndex + 1) + m_bChart;
            }
            else if (plot->m_plotType == L"BoxLine" ||
                plot->m_plotType == L"TironeLevels" ||
                plot->m_plotType == L"QuadrantLines")
            {
                getCandleRange(plot);
                double nHigh = m_nHighChart, nLow = m_nLowChart;
                index1 = getChartIndexByDate(plot->m_key1);
                index2 = getChartIndexByDate(plot->m_key2);
                int minIndex = index1 > index2 ? index2 : index1;
                int maxIndex = index1 > index2 ? index1 : index2;
                plot->m_key1 = getChartDateByIndex(minIndex);
                plot->m_key2 = getChartDateByIndex(maxIndex);
                plot->m_value1 = nHigh;
                plot->m_value2 = nLow;
            }
            if (plot->m_key1 > 0)
            {
                index1 = getChartIndexByDate(plot->m_key1);
                mpx1 = getChartX(index1);
                mpy1 = getChartY(0, plot->m_value1);
                if (m_sPlot == plot)
                {
                    FCRect elRect = { (int)(mpx1 - m_plotPointSizeChart), (int)(mpy1 - m_plotPointSizeChart), (int)(mpx1 + m_plotPointSizeChart), (int)(mpy1 + m_plotPointSizeChart) };
                    paint->fillEllipse(plot->m_pointColor, elRect);
                }
            }
            if (plot->m_key2 > 0)
            {
                index2 = getChartIndexByDate(plot->m_key2);
                mpx2 = getChartX(index2);
                mpy2 = getChartY(0, plot->m_value2);
                if (m_sPlot == plot)
                {
                    FCRect elRect = { (int)(mpx2 - m_plotPointSizeChart),
                        (int)(mpy2 - m_plotPointSizeChart),
                        (int)(mpx2 + m_plotPointSizeChart),
                        (int)(mpy2 + m_plotPointSizeChart) };
                    paint->fillEllipse(
                        plot->m_pointColor,
                        elRect);
                }
            }
            if (plot->m_key3 > 0)
            {
                index3 = getChartIndexByDate(plot->m_key3);
                mpx3 = getChartX(index3);
                mpy3 = getChartY(0, plot->m_value3);
                if (m_sPlot == plot)
                {
                    FCRect elRect = { (int)(mpx3 - m_plotPointSizeChart),
                        (int)(mpy3 - m_plotPointSizeChart),
                        (int)(mpx3 + m_plotPointSizeChart),
                        (int)(mpy3 + m_plotPointSizeChart) };
                    paint->fillEllipse(
                        plot->m_pointColor,
                        elRect);
                }
            }
            if (plot->m_plotType == L"Line")
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (mpx2 == mpx1)
                {
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
            }
            else if (plot->m_plotType == L"ArrowSegment")
            {
                int arrowSize = 24;
                double slopy = 0, cosy = 0, siny = 0;
                slopy = atan2((double)(mpy1 - mpy2), (double)(mpx1 - mpx2));
                cosy = cos(slopy);
                siny = sin(slopy);
                FCPoint ptPoint = { 0, 0 };
                ptPoint.x = mpx2;
                ptPoint.y = mpy2;
                ArrayList<FCPoint> pts;
                FCPoint zeroPoint = { 0, 0 };
                pts.add(zeroPoint);
                pts.add(zeroPoint);
                pts.add(zeroPoint);
                pts.set(0, ptPoint);
                FCPoint pp3 = { (int)(ptPoint.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)), (int)(ptPoint.y + (arrowSize * siny + (arrowSize / 2.0 * cosy) + 0.5)) };
                pts.set(1, pp3);
                FCPoint pp4 = {(int)(ptPoint.x + (arrowSize * cosy + arrowSize / 2.0 * siny + 0.5)), (int)(ptPoint.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5)) };
                pts.set(2, pp4);
                arrowSize = 20;
                FCPoint ptPoint2 = { 0, 0 };
                ptPoint2.x = mpx2;
                ptPoint2.y = mpy2;
                ArrayList<FCPoint> pts2;
                pts2.add(zeroPoint);
                pts2.add(zeroPoint);
                pts2.add(zeroPoint);
                pts2.set(0, ptPoint2);
                FCPoint pp1 = { (int)(ptPoint2.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)), (int)(ptPoint2.y + (arrowSize * siny + (arrowSize / 2.0 * cosy) + 0.5)) };
                pts2.set(1, pp1);
                FCPoint pp2 = {(int)(ptPoint2.x + (arrowSize * cosy + arrowSize / 2.0 * siny + 0.5)), (int)(ptPoint2.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5))};
                pts2.set(2, pp2);
                lineXY(pts2.get(1).x, pts2.get(1).y, pts2.get(2).x, pts2.get(2).y, 0, 0);
                double newX1 = 0, newY1 = 0, newX2 = 0, newY2 = 0;
                if (pts2.get(1).x > pts2.get(2).x)
                {
                    newX1 = pts2.get(2).x + (pts2.get(1).x - pts2.get(2).x) / 3;
                    newX2 = pts2.get(2).x + (pts2.get(1).x - pts2.get(2).x) * 2 / 3;
                }
                else
                {
                    newX1 = pts2.get(1).x + (pts2.get(2).x - pts2.get(1).x) / 3;
                    newX2 = pts2.get(1).x + (pts2.get(2).x - pts2.get(1).x) * 2 / 3;
                }
                if (m_kChart == 0 && m_bChart == 0)
                {
                    if (pts2.get(1).y > pts2.get(2).y)
                    {
                        newY1 = pts2.get(2).y + (pts2.get(1).y - pts2.get(2).y) / 3;
                        newY2 = pts2.get(2).y + (pts2.get(1).y - pts2.get(2).y) * 2 / 3;
                    }
                    else
                    {
                        newY1 = pts2.get(1).y + (pts2.get(2).y - pts2.get(1).y) / 3;
                        newY2 = pts2.get(1).y + (pts2.get(2).y - pts2.get(1).y) * 2 / 3;
                    }
                }
                else
                {
                    newY1 = (m_kChart * newX1) + m_bChart;
                    newY2 = (m_kChart * newX2) + m_bChart;
                }
                FCPoint pp5 = { (int)newX1, (int)newY1 };
                pts2.set(1, pp5);
                FCPoint pp6 = { (int)newX2, (int)newY2 };
                pts2.set(2, pp6);
                ArrayList<FCPoint> drawPoints;
                drawPoints.add(zeroPoint);
                drawPoints.add(zeroPoint);
                drawPoints.add(zeroPoint);
                drawPoints.add(zeroPoint);
                drawPoints.add(zeroPoint);
                drawPoints.add(zeroPoint);
                FCPoint pp7 = { ptPoint.x, ptPoint.y };
                drawPoints.set(0, pp7);
                FCPoint pp8 = { pts.get(1).x, pts.get(1).y };
                drawPoints.set(1, pp8);
                if (mpy1 >= mpy2)
                {
                    FCPoint pp9 = { pts2.get(1).x, pts2.get(1).y };
                    drawPoints.set(2, pp9);
                }
                else
                {
                    FCPoint pp9 = { pts2.get(2).x, pts2.get(2).y };
                    drawPoints.set(2, pp9);
                }
                FCPoint pp10 = { mpx1, mpy1 };
                drawPoints.set(3, pp10);
                if (mpy1 >= mpy2)
                {
                    FCPoint pp11 = { pts2.get(2).x, pts2.get(2).y };
                    drawPoints.set(4, pp11);
                }
                else
                {
                    FCPoint pp11 = { pts2.get(1).x, pts2.get(1).y };
                    drawPoints.set(4, pp11);
                }
                FCPoint pp12 = { pts.get(2).x, pts.get(2).y };
                drawPoints.set(5, pp12);

                paint->fillPolygon(plot->m_lineColor, drawPoints.m_ary, 6);
            }
            else if (plot->m_plotType == L"AngleLine")
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (mpx2 == mpx1)
                {
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
                lineXY(mpx1, mpy1, mpx3, mpy3, 0, 0);
                if (mpx3 == mpx1)
                {
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
            }
            else if (plot->m_plotType == L"Parallel")
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (mpx2 == mpx1)
                {
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + m_bChart;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + m_bChart;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
                double newB = mpy3 - m_kChart * mpx3;
                if (mpx2 == mpx1)
                {
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx3, 0, mpx3, divHeight);
                }
                else
                {
                    double newX1 = m_leftVScaleWidth;
                    double newY1 = newX1 * m_kChart + newB;
                    double newX2 = size.cx - m_rightVScaleWidth;
                    double newY2 = newX2 * m_kChart + newB;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)newX1, (int)newY1, (int)newX2, (int)newY2);
                }
            }
            else if (plot->m_plotType == L"Percent")
            {
                ArrayList<int> list = getPercentParams(mpy1, mpy2);
                ArrayList<String> texts;
                texts.add(L"0%");
                texts.add(L"25%");
                texts.add(L"50%");
                texts.add(L"75%");
                texts.add(L"100%");
                for (int j = 0; j < list.size(); j++)
                {
                    paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, m_leftVScaleWidth,
                        list.get(j), size.cx - m_rightVScaleWidth, list.get(j));
                    FCSize tSize = paint->textSize(texts.get(j), getFont());
                    FCRect dRect = { m_leftVScaleWidth + 5, list.get(j) - tSize.cy - 2, m_leftVScaleWidth + 5 + tSize.cx, list.get(j) - 2};
                    paint->drawText(texts.get(j), getTextColor(), getFont(), dRect);
                }
            }
            else if (plot->m_plotType == L"FiboTimezone")
            {
                int fValue = 1;
                int aIndex = index1;
                int pos = 1;
                paint->drawLine(
                    plot->m_lineColor, plot->m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                FCSize tSize = paint->textSize(L"1", getFont());
                FCRect dRect = { mpx1, divHeight - tSize.cy, mpx1 + tSize.cx, divHeight };
                paint->drawText(
                    L"1", getTextColor(), getFont(), dRect);
                while (aIndex + fValue <= m_lastVisibleIndex)
                {
                    fValue = fibonacciValue(pos);
                    int newIndex = aIndex + fValue;
                    double newX = getChartX(newIndex);
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)newX, 0, (int)newX, divHeight);
                    FCSize tSize2 = paint->textSize(FCTran::doubleToStr(fValue), getFont());
                    FCRect dRect2 = { (int)newX,
                        divHeight - tSize2.cy, (int)newX + tSize2.cx, divHeight };
                    paint->drawText(FCTran::doubleToStr(fValue), getTextColor(), getFont(), dRect2);
                    pos++;
                }
            }
            else if (plot->m_plotType == L"SpeedResist")
            {
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                if (mpx1 != mpx2 && mpy1 != mpy2)
                {
                    FCPoint firstP = { mpx2, mpy2 - (mpy2 - mpy1) / 3 };
                    FCPoint secondP = { mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3 };
                    FCPoint startP = { mpx1, mpy1 };
                    double fK = 0, fB = 0, sK = 0, sB = 0;
                    lineXY(startP.x, startP.y, firstP.x, firstP.y, 0, 0);
                    fK = m_kChart;
                    fB = m_bChart;
                    lineXY(startP.x, startP.y, secondP.x, secondP.y, 0, 0);
                    sK = m_kChart;
                    sB = m_bChart;
                    double newYF = 0, newYS = 0;
                    double newX = 0;
                    if (mpx2 > mpx1)
                    {
                        newYF = fK * (size.cx - m_rightVScaleWidth) + fB;
                        newYS = sK * (size.cx - m_rightVScaleWidth) + sB;
                        newX = (size.cx - m_rightVScaleWidth);
                    }
                    else
                    {
                        newYF = fB;
                        newYS = sB;
                        newX = m_leftVScaleWidth;
                    }
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, startP.x, startP.y, (int)newX, (int)newYF);
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, startP.x, startP.y, (int)newX, (int)newYS);
                }
            }
            else if (plot->m_plotType == L"FiboFanline")
            {
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                if (mpx1 != mpx2 && mpy1 != mpy2)
                {
                    FCPoint firstP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.382) };
                    FCPoint secondP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.5) };
                    FCPoint thirdP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.618) };
                    FCPoint startP = { (int)mpx1, (int)mpy1 };
                    ArrayList<FCPoint> listP;
                    listP.add(firstP);
                    listP.add(secondP);
                    listP.add(thirdP);
                    int listSize = listP.size();
                    for (int j = 0; j < listSize; j++)
                    {
                        //获取直线参数
                        lineXY(startP.x, startP.y, listP.get(j).x, listP.get(j).y, 0, 0);
                        double newX = 0;
                        double newY = 0;
                        if (mpx2 > mpx1)
                        {
                            newY = m_kChart * (size.cx - m_rightVScaleWidth) +
                                m_bChart;
                            newX = (size.cx - m_rightVScaleWidth);
                        }
                        else
                        {
                            newY = m_bChart;
                            newX = m_leftVScaleWidth;
                        }
                        paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, startP.x, startP.y,
                            (int)newX, (int)newY);
                    }
                }
            }
            else if (plot->m_plotType == L"LRLine")
            {
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot->m_plotType == L"LRBand")
            {
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                getLRBandRange(plot, m_kChart, m_bChart);
                mpy1 = getChartY(0, plot->m_value1 + m_upSubValue);
                mpy2 = getChartY(0, plot->m_value2 + m_upSubValue);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                mpy1 = getChartY(0, plot->m_value1 - m_downSubValue);
                mpy2 = getChartY(0, plot->m_value2 - m_downSubValue);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot->m_plotType == L"LRChannel")
            {
                getLRBandRange(plot, m_kChart, m_bChart);
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                double rightX = size.cx - m_rightVScaleWidth;
                double rightY = rightX * m_kChart + m_bChart;
                paint->drawLine(
                    plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
                mpy1 = getChartY(0, plot->m_value1 + m_upSubValue);
                mpy2 = getChartY(0, plot->m_value2 + m_upSubValue);
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                rightY = rightX * m_kChart + m_bChart;
                paint->drawLine(
                    plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
                mpy1 = getChartY(0, plot->m_value1 - m_downSubValue);
                mpy2 = getChartY(0, plot->m_value2 - m_downSubValue);
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                rightY = rightX * m_kChart + m_bChart;
                paint->drawLine(
                    plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
            }
            else if (plot->m_plotType == L"Segment")
            {
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot->m_plotType == L"Ray")
            {
                lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                if (m_kChart != 0 || m_bChart != 0)
                {
                    double leftX = m_leftVScaleWidth;
                    double leftY = leftX * m_kChart + m_bChart;
                    double rightX = size.cx - m_rightVScaleWidth;
                    double rightY = rightX * m_kChart + m_bChart;
                    if (mpx1 >= mpx2)
                    {
                        paint->drawLine(
                            plot->m_lineColor, plot->m_lineWidth, 0, (int)leftX, (int)leftY, mpx1, mpy1);
                    }
                    else
                    {
                        paint->drawLine(
                            plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, (int)rightX, (int)rightY);
                    }
                }
                //垂直时
                else
                {
                    if (mpy1 >= mpy2)
                    {
                        paint->drawLine(
                            plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx1, 0);
                    }
                    else
                    {
                        paint->drawLine(
                            plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx1, divHeight);
                    }
                }
            }
            else if (plot->m_plotType == L"Triangle")
            {
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx2, mpy2, mpx3, mpy3);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx3, mpy3);
            }
            else if (plot->m_plotType == L"SymmetricTriangle")
            {
                if (mpx2 != mpx1)
                {
                    double a = (double)(mpy2 - mpy1) / (double)(mpx2 - mpx1);
                    double b = mpy1 - a * mpx1;
                    double c = -a;
                    double d = mpy3 - c * mpx3;
                    double leftX = m_leftVScaleWidth;
                    double leftY = leftX * a + b;
                    double rightX = size.cx - m_rightVScaleWidth;
                    double rightY = rightX * a + b;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)leftX, (int)leftY, (int)rightX, (int)rightY);
                    leftY = leftX * c + d;
                    rightY = rightX * c + d;
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, (int)leftX, (int)leftY, (int)rightX, (int)rightY);
                }
                else
                {
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx1, 0, mpx1, divHeight);
                    paint->drawLine(
                        plot->m_lineColor, plot->m_lineWidth, 0, mpx3, 0, mpx3, divHeight);
                }
            }
            else if (plot->m_plotType == L"Rect")
            {
                double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                paint->drawRect(plot->m_lineColor, plot->m_lineWidth, 0, sX1, sY1, sX2, sY2);
            }
            else if (plot->m_plotType == L"Cycle")
            {
                int r = (int)sqrt(
                    (double)((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)));
                paint->drawEllipse(plot->m_lineColor, plot->m_lineWidth, 0, mpx1 - r, mpy1 - r,
                    mpx1 + r, mpy1 + r);
            }
            else if (plot->m_plotType == L"CircumCycle")
            {
                ellipseOR(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                paint->drawEllipse(
                    plot->m_lineColor,
                    plot->m_lineWidth,
                    0,
                    (int)(m_oXChart - m_rChart),
                    (int)(m_oYChart - m_rChart),
                    (int)(m_oXChart + m_rChart),
                    (int)(m_oYChart + m_rChart));
            }
            else if (plot->m_plotType == L"Ellipse")
            {
                double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                if (mpx1 <= mpx2)
                {
                    x1 = mpx2;
                    y1 = mpy2;
                    x2 = mpx1;
                    y2 = mpy1;
                }
                else
                {
                    x1 = mpx1;
                    y1 = mpy1;
                    x2 = mpx2;
                    y2 = mpy2;
                }
                double x = x1 - (x1 - x2);
                double y = 0;
                double width = (x1 - x2) * 2;
                double height = 0;
                if (y1 >= y2)
                {
                    height = (y1 - y2) * 2;
                }
                else
                {
                    height = (y2 - y1) * 2;
                }
                y = y2 - height / 2;
                paint->drawEllipse(
                    plot->m_lineColor, plot->m_lineWidth, 0, (int)x, (int)y, (int)(x + width), (int)(y + height));
            }
            else if (plot->m_plotType == L"ParalleGram")
            {
                parallelogram(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx1, mpy1, mpx2, mpy2);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx2, mpy2, mpx3, mpy3);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, mpx3, mpy3,
                    (int)m_x4Chart, (int)m_y4Chart);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, (int)m_x4Chart,
                    (int)m_y4Chart, mpx1, mpy1);
            }
            else if (plot->m_plotType == L"BoxLine")
            {
                int sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                int sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                int sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                int sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                paint->drawRect(plot->m_lineColor, plot->m_lineWidth, 0, sX1, sY1, sX2, sY2);
                double absValue = index2 - index1 > 0 ? index2 - index1 : index1 - index2;
                String bText = FCTran::intToStr(absValue + 1);
                FCSize tSize = paint->textSize(bText, getFont());
                FCRect dRect = { sX1 + 2, sY1 + 2, sX1 + 2 + tSize.cx, sY1 + 2 + tSize.cy };
                paint->drawText(FCTran::intToStr(absValue + 1), getTextColor(),
                    getFont(), dRect);
                ArrayList<double> closeList;
                for (int j = index1; j <= index2; j++)
                {
                    closeList.add(m_data.get(j).m_close);
                }
                double avgClose = avgValue(&closeList);
                int closeY = getChartY(0, avgClose);
                paint->drawLine(
                    plot->m_lineColor, plot->m_lineWidth, 0, sX1, closeY, sX2, closeY);
                String drawAvg = FCTran::getValueByDigit(avgClose, m_candleDigit);
                tSize = paint->textSize(drawAvg, getFont());
                FCRect dRect2 = { sX1 + 2, closeY - tSize.cy - 2, sX1 + 2 + tSize.cx, closeY - 2 };
                paint->drawText(drawAvg, getTextColor(), getFont(), dRect2);
            }
            else if (plot->m_plotType == L"TironeLevels")
            {
                double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, sX1, sY1, sX2, sY1);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, sX1, sY2, sX2, sY2);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, sX1 + (sX2 - sX1) / 2,
                    sY1, sX1 + (sX2 - sX1) / 2, sY2);
                double t2 = m_nHighChart - (m_nHighChart - m_nLowChart) / 3,
                    t3 = m_nHighChart - (m_nHighChart - m_nLowChart) / 2,
                    t4 = m_nHighChart - 2 * (m_nHighChart - m_nLowChart) / 3;
                ArrayList<double> tList;
                tList.add(t2);
                tList.add(t3);
                tList.add(t4);
                for (int j = 0; j < tList.size(); j++)
                {
                    int y = getChartY(0, tList.get(j));
                    //画直线
                    paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, m_leftVScaleWidth,
                        y, size.cx - m_rightVScaleWidth, y);
                    String str = FCTran::getValueByDigit(tList.get(j), m_candleDigit);
                    FCSize tSize = paint->textSize(str, getFont());
                    FCRect dRect = { m_leftVScaleWidth + 2, y - tSize.cy - 2, m_leftVScaleWidth + 2 + tSize.cx, y - 2 };
                    paint->drawText(str, getTextColor(), getFont(), dRect);
                }
            }
            else if (plot->m_plotType == L"QuadrantLines")
            {
                double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, sX1, sY1, sX2, sY1);
                paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, sX1, sY2, sX2, sY2);
                double t2 = m_nHighChart - (m_nHighChart - m_nLowChart) / 4,
                    t3 = m_nHighChart - (m_nHighChart - m_nLowChart) / 2,
                    t4 = m_nHighChart - 3 * (m_nHighChart - m_nLowChart) / 4;
                ArrayList<double> tList;
                tList.add(t2);
                tList.add(t3);
                tList.add(t4);
                for (int j = 0; j < tList.size(); j++)
                {
                    int y = getChartY(0, tList.get(j));
                    //画直线
                    paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, sX1, y, sX2, y);
                }
            }
            else if (plot->m_plotType == L"GoldenRatio")
            {
                double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                ArrayList<double> ranges;
                ranges.add(0);
                ranges.add(0.236);
                ranges.add(0.382);
                ranges.add(0.5);
                ranges.add(0.618);
                ranges.add(0.809);
                ranges.add(1);
                ranges.add(1.382);
                ranges.add(1.618);
                ranges.add(2);
                ranges.add(2.382);
                ranges.add(2.618);
                for (int j = 0; j < ranges.size(); j++)
                {
                    double newY = sY1 <= sY2
                        ? sY1 + (sY2 - sY1) * ranges.get(j)
                        : sY2 + (sY1 - sY2) * (1 - ranges.get(j));
                    paint->drawLine(plot->m_lineColor, plot->m_lineWidth, 0, m_leftVScaleWidth,
                        (int)newY, size.cx - m_rightVScaleWidth, (int)newY);
                    FCPoint newPoint = { 0, (int)newY };
                    double value = getCandleDivValue(newPoint);
                    String str = FCTran::getValueByDigit(value, m_candleDigit);
                    FCSize tSize = paint->textSize(str, getFont());
                    FCRect dRect = { m_leftVScaleWidth + 2, (int)newY - tSize.cy - 2, m_leftVScaleWidth + 2 + tSize.cx, (int)newY - 2 };
                    paint->drawText(str, getTextColor(), getFont(), dRect);
                }
            }
        }
        paint->setClip(clipRect);
    }

    void FCChart::drawChartStock(FCPaint* paint, const FCRect& clipRect) {
        int candleHeight = getCandleDivHeight();
        int volHeight = getVolDivHeight();
        int indHeight = getIndDivHeight();
        FCSize size = getSize();
        bool isTrend = m_cycle == L"trend";
        int cWidth = (int)((m_hScalePixel - 3) / 2);
        if (cWidth < 0)
        {
            cWidth = 0;
        }
        int lastValidIndex = m_lastVisibleIndex;
        if (m_lastValidIndex != -1)
        {
            lastValidIndex = m_lastValidIndex;
        }
        if (m_data.size() > 0)
        {
            int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
            FCRect cRect = { m_leftVScaleWidth > clipRect.left ? m_leftVScaleWidth : clipRect.left, 0 > clipRect.top ? 0 : clipRect.top, size.cx - m_rightVScaleWidth < clipRect.bottom ? size.cx - m_rightVScaleWidth : clipRect.right , candleHeight < clipRect.bottom ? candleHeight : clipRect.bottom };
            paint->setClip(cRect);
            if (isTrend)
            {
                ArrayList<FCPoint> points;
                for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                {
                    int x = getChartX(i);
                    double close = m_data.get(i).m_close;
                    int closeY = getChartY(0, close);
      FCPoint point = {x, closeY};
      points.add(point);
                }
                paint->drawPolyline(m_indicatorColors.get(7), m_lineWidthChart, 0, points.m_ary, points.size());
            }
            bool hasMinTag = false, hasMaxTag = false;
            for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
            {
                int x = getChartX(i);
                double open = m_data.get(i).m_open;
                double close = m_data.get(i).m_close;
                double high = m_data.get(i).m_high;
                double low = m_data.get(i).m_low;
                int openY = getChartY(0, open);
                int closeY = getChartY(0, close);
                int highY = getChartY(0, high);
                int lowY = getChartY(0, low);
                if (close >= open)
                {
                    if (isTrend)
                    {
                    }
                    else
                    {
                        paint->drawLine(
                            m_upColor, m_lineWidthChart, 0, x, highY, x, lowY);
                        if (cWidth > 0)
                        {
                            if (close == open)
                            {
                                paint->drawLine(m_upColor, m_lineWidthChart, 0, x - cWidth,
                                    closeY, x + cWidth, closeY);
                            }
                            else
                            {
                                if (m_candleStyle == L"rect2")
{
    paint->fillRect(m_backColor, x - cWidth, closeY, x + cWidth, openY);
    paint->drawRect(m_upColor, 1, 0, x - cWidth, closeY, x + cWidth + 1, openY);
}
else{
    paint->fillRect(m_upColor, x - cWidth, closeY, x + cWidth, openY);
}
                            }
                        }
                    }
                }
                else
                {
                    if (isTrend)
                    {
                    }
                    else
                    {
                        paint->drawLine(
                            m_downColor, m_lineWidthChart, 0, x, highY, x, lowY);
                        if (cWidth > 0)
                        {
                            paint->fillRect(
                                m_downColor, x - cWidth, openY, x + cWidth, closeY);
                        }
                    }
                }
                if (m_selectShape == L"CANDLE")
                {
                    int kPInterval = maxVisibleRecord / 30;
                    if (kPInterval < 2)
                    {
                        kPInterval = 3;
                    }
                    if (i % kPInterval == 0)
                    {
                        if (isTrend)
                        {
                        }
                        else
                        {
                            paint->fillRect(
                                m_indicatorColors.get(0), x - 3, closeY - 3, x + 3, closeY + 3);
                        }
                    }
                }
                if (!isTrend)
                {
                    if (!hasMaxTag)
                    {
                        if (high == m_candleMax)
                        {
                            String tag = FCTran::getValueByDigit(high, m_candleDigit);
                            FCSize tSize = paint->textSize(tag, getFont());
                            FCRect dRect = { x - tSize.cx / 2,
                                highY - tSize.cy / 2 - 2, x + tSize.cx / 2, highY + tSize.cy / 2 - 2 };
                            paint->drawText(tag, getTextColor(), getFont(), dRect);
                            hasMaxTag = true;
                        }
                    }
                    if (!hasMinTag)
                    {
                        if (low == m_candleMin)
                        {
                            String tag = FCTran::getValueByDigit(low, m_candleDigit);
                            FCSize tSize = paint->textSize(tag, getFont());
                            FCRect dRect = { x - tSize.cx / 2,
                                lowY + 2 + tSize.cy / 2, x + tSize.cx / 2,
                                lowY + 2 + tSize.cy * 3 / 2 };
                            paint->drawText(tag, getTextColor(), getFont(), dRect);
                            hasMinTag = true;
                        }
                    }
                }
            }
            paint->setClip(clipRect);
            for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
            {
                int x = getChartX(i);
                double open = m_data.get(i).m_open;
                double close = m_data.get(i).m_close;
                int volY = 0;
                int zeroY = 0;
                if (volHeight > 0)
                {
                    double volume = m_data.get(i).m_volume;
                    volY = getChartY(1, volume);
                    zeroY = getChartY(1, 0);
                }
                if (close >= open)
                {
                    if (isTrend)
                    {
                        if (volHeight > 0)
                        {
                            paint->drawLine(m_indicatorColors.get(6), m_lineWidthChart, 0, x,
                                volY, x, zeroY);
                        }
                    }
                    else
                    {
                        if (cWidth > 0)
                        {
                            if (volHeight > 0)
                            {
                                if (m_barStyle == L"rect2")
{
    paint->fillRect(m_backColor, x - cWidth, volY, x + cWidth, zeroY);
    paint->drawRect(m_upColor, 1, 0, x - cWidth, volY, x + cWidth + 1, zeroY);
}
else{
    paint->fillRect(m_upColor, x - cWidth, volY, x + cWidth, zeroY);
}
                            }
                        }
                        else
                        {
                            if (volHeight > 0)
                            {
                                paint->drawLine(m_upColor, m_lineWidthChart, 0, x - cWidth,
                                    volY, x + cWidth, zeroY);
                            }
                        }
                    }
                }
                else
                {
                    if (isTrend)
                    {
                        if (volHeight > 0)
                        {
                            paint->drawLine(m_indicatorColors.get(6), m_lineWidthChart, 0, x,
                                volY, x, zeroY);
                        }
                    }
                    else
                    {
                        if (cWidth > 0)
                        {
                            if (volHeight > 0)
                            {
                                paint->fillRect(
                                    m_downColor, x - cWidth, volY, x + cWidth, zeroY);
                            }
                        }
                        else
                        {
                            if (volHeight > 0)
                            {
                                paint->drawLine(m_downColor, m_lineWidthChart, 0,
                                    x - cWidth, volY, x + cWidth, zeroY);
                            }
                        }
                    }
                }
                if (m_selectShape == L"VOL")
                {
                    int kPInterval = maxVisibleRecord / 30;
                    if (kPInterval < 2)
                    {
                        kPInterval = 3;
                    }
                    if (i % kPInterval == 0)
                    {
                        paint->fillRect(
                            m_indicatorColors.get(0), x - 3, volY - 3, x + 3, volY + 3);
                    }
                }
            }
            if (!isTrend)
            {
                FCRect ccRect = { m_leftVScaleWidth > clipRect.left ? m_leftVScaleWidth : clipRect.left, 0 > clipRect.top ? 0 : clipRect.top, size.cx - m_rightVScaleWidth < clipRect.bottom ? size.cx - m_rightVScaleWidth : clipRect.right , candleHeight < clipRect.bottom ? candleHeight : clipRect.bottom };
                paint->setClip(ccRect);
                if (m_mainIndicator == L"BOLL")
                {
                    drawChartLines(paint, clipRect, 0,
                        &m_bollMid, m_indicatorColors.get(0),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"MID") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_bollUp, m_indicatorColors.get(1),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"UP") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_bollDown, m_indicatorColors.get(2),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"DOWN") ? true : false);
                }
                else if (m_mainIndicator == L"MA")
                {
                    drawChartLines(paint, clipRect, 0,
                        &m_ma5, m_indicatorColors.get(0),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"5") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_ma10, m_indicatorColors.get(1),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"10") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_ma20, m_indicatorColors.get(2),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"20") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_ma30, m_indicatorColors.get(5),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"30") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_ma120, m_indicatorColors.get(4),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"120") ? true : false);
                    drawChartLines(paint, clipRect, 0,
                        &m_ma250, m_indicatorColors.get(3),
                        (m_selectShape == m_mainIndicator &&
                            m_selectShapeEx == L"250") ? true : false);
                }
                paint->setClip(clipRect);
            }
            if (indHeight > 0)
            {
                if (m_showIndicator == L"MACD")
                {
                    int zeroY = getChartY(2, 0);
                    paint->drawLine(m_indicatorColors.get(4), m_lineWidthChart, 0,
                        m_leftVScaleWidth, zeroY, getChartX(m_lastVisibleIndex), zeroY);
                    for (int i = m_firstVisibleIndex; i <= lastValidIndex; i++)
                    {
                        int x = getChartX(i);
                        double macd = m_allmacdarr.get(i);
                        int macdY = getChartY(2, macd);
                        if (macdY < zeroY)
                        {
                            paint->drawLine(m_indicatorColors.get(3), m_lineWidthChart, 0, x,
                                macdY, x, zeroY);
                        }
                        else
                        {
                            paint->drawLine(m_indicatorColors.get(4), m_lineWidthChart, 0, x,
                                macdY, x, zeroY);
                        }
                        if (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"MACD")
                        {
                            int kPInterval = maxVisibleRecord / 30;
                            if (kPInterval < 2)
                            {
                                kPInterval = 3;
                            }
                            if (i % kPInterval == 0)
                            {
                                paint->fillRect(
                                    m_indicatorColors.get(4), x - 3, macdY - 3, x + 3, macdY + 3);
                            }
                        }
                    }
                    drawChartLines(paint, clipRect, 2,
                        &m_alldifarr, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"DIF") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_alldeaarr, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"DEA") ? true : false);
                }
                else if (m_showIndicator == L"KDJ")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_kdjK, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"K") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_kdjD, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"D") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_kdjJ, m_indicatorColors.get(2),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"J") ? true : false);
                }
                else if (m_showIndicator == L"RSI")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_rsi1, m_indicatorColors.get(5),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"6") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_rsi2, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"12") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_rsi3, m_indicatorColors.get(2),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"24") ? true : false);
                }
                else if (m_showIndicator == L"BIAS")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_bias1, m_indicatorColors.get(5),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"1") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_bias2, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"2") ? true : false);
                    drawChartLines(
                        paint, clipRect, 2, &m_bias3,
                        m_indicatorColors.get(2),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"3") ? true : false);
                }
                else if (m_showIndicator == L"ROC")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_roc, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"ROC") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_rocMa, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"ROCMA") ? true : false);
                }
                else if (m_showIndicator == L"WR")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_wr1, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"1") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_wr2, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"2") ? true : false);
                }
                else if (m_showIndicator == L"CCI")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_cci, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator) ? true : false);
                }
                else if (m_showIndicator == L"BBI")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_bbi, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator) ? true : false);
                }
                else if (m_showIndicator == L"TRIX")
                {
                    drawChartLines(paint, clipRect, 2,
                        &m_trix, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"TRIX") ? true : false);
                    drawChartLines(paint, clipRect, 2,
                        &m_trixMa, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator &&
                            m_selectShapeEx == L"TRIXMA") ? true : false);
                }
                else if (m_showIndicator == L"DMA")
                {
                    drawChartLines(paint, clipRect, 2, &m_dma1, m_indicatorColors.get(0),
                        (m_selectShape == m_showIndicator && m_selectShapeEx == L"DIF") ? true : false);
                    drawChartLines(paint, clipRect, 2, &m_dma2, m_indicatorColors.get(1),
                        (m_selectShape == m_showIndicator && m_selectShapeEx == L"DIFMA") ? true : false);
                }
            }
        }
        //绘制扩展线条
        if (m_shapes.size() > 0)
        {
            for (int i = 0; i < m_shapes.size(); i++)
            {
                BaseShape *shape = m_shapes.get(i);
                if (shape->m_shapeType == L"bar")
                {
                    for (int j = m_firstVisibleIndex; j <= lastValidIndex; j++)
                    {
                        if (shape->m_showHideDatas.size() > j &&
                            FCTran::doubleToStr(shape->m_showHideDatas.get(j)) == L"0")
                        {
                            continue;
                        }
                        int x = getChartX(j);
                        int y1 = 0;
                        if (shape->m_leftOrRight)
                        {
                            y1 = getChartY(shape->m_divIndex, shape->m_datas.get(j));
                        }
                        else
                        {
                            y1 = getChartYInRight(shape->m_divIndex, shape->m_datas.get(j));
                        }
                        if (shape->m_style != L"2color")
                        {
                            int y2 = 0;
                            if (shape->m_leftOrRight)
                            {
                                y2 = getChartY(shape->m_divIndex, shape->m_datas2.get(j));
                            }
                            else
                            {
                                y2 = getChartYInRight(shape->m_divIndex, shape->m_datas2.get(j));
                            }
                            if (y1 >= y2)
                            {
                                paint->fillRect(shape->m_color, x - cWidth, y2, x + cWidth, y1);
                            }
                            else
                            {
                                paint->fillRect(shape->m_color, x - cWidth, y1, x + cWidth, y2);
                            }
                        }
                        else
                        {
                            int y2 = 0;
                            if (shape->m_leftOrRight)
                            {
                                y2 = getChartY(shape->m_divIndex, 0);
                            }
                            else
                            {
                                y2 = getChartYInRight(shape->m_divIndex, 0);
                            }
                            if (y1 >= y2)
                            {
                                paint->drawLine(shape->m_color2, 1, 0, x, y1, x, y2);
                            }
                            else
                            {
                                paint->drawLine(shape->m_color, 1, 0, x, y1, x, y2);
                            }
                            if (j == lastValidIndex)
                            {
                                paint->drawLine(shape->m_color2, 1, 0, m_leftVScaleWidth, y2,
                                    size.cx - m_rightVScaleWidth, y2);
                            }
                        }
                    }
                }
                else if (shape->m_shapeType == L"text")
                {
                    for (int j = m_firstVisibleIndex; j <= lastValidIndex; j++)
                    {
                        int x = getChartX(j);
                        if (shape->m_datas.get(j) != 0)
                        {
                            int y1 = 0;
                            if (shape->m_leftOrRight)
                            {
                                y1 = getChartY(shape->m_divIndex, shape->m_value);
                            }
                            else
                            {
                                y1 = getChartYInRight(shape->m_divIndex, shape->m_value);
                            }
                            String drawText = shape->m_text;
                            FCSize tSize = paint->textSize(drawText, getFont());
                            FCRect dRect = { x - tSize.cx / 2, y1 - tSize.cy / 2, x + tSize.cx / 2, y1 + tSize.cy / 2 };
                            paint->drawText(drawText, shape->m_color, getFont(), dRect);
                        }
                    }
                }
                else
                {
                    if (shape->m_leftOrRight)
                    {
                        drawChartLines(paint, clipRect, shape->m_divIndex,
                            &shape->m_datas, shape->m_color,
                            (m_selectShape == shape->m_shapeName) ? true : false);
                    }
                    else
                    {
                        drawChartLinesInRight(paint, clipRect, shape->m_divIndex,
                            &shape->m_datas, shape->m_color,
                            (m_selectShape == shape->m_shapeName) ? true : false);
                    }
                }
            }
        }
    }

    void FCChart::drawChartCrossLine(FCPaint* paint, const FCRect& clipRect) {
        if (m_data.size() == 0)
        {
            return;
        }
        FCSize size = getSize();
        int candleDivHeight = getCandleDivHeight();
        int volDivHeight = getVolDivHeight();
        int indDivHeight = getIndDivHeight();
        int indDivHeight2 = getIndDivHeight2();
        int crossLineIndex = m_crossStopIndex;
        if (crossLineIndex == -1 || !m_showCrossLine)
        {
            if (m_lastValidIndex != -1)
                {
                    crossLineIndex = m_lastValidIndex;
                }
                else
                {
                    crossLineIndex = m_lastVisibleIndex;
                }
        }
if(crossLineIndex == -1)
{
    return;
}
        if (volDivHeight > 0)
        {
            ArrayList<String> drawTitles;
            ArrayList<Long> drawColors;
            drawTitles.add((String)L"VOL " +
                FCTran::getValueByDigit(m_data.get(crossLineIndex).m_volume / m_magnitude, m_volDigit));
            drawColors.add(getTextColor());
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape *shape = m_shapes.get(i);
                    if (shape->m_divIndex == 1)
                    {
                        if ((int)shape->m_title.length() > 0)
                        {
                            if (shape->m_shapeType == L"bar" && shape->m_style == L"2color")
                            {
                                drawTitles.add(shape->m_title +
                                    L" " +
                                    FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_volDigit));
                                drawColors.add(shape->m_color2);
                            }
                            else
                            {
                                if (shape->m_shapeType != L"text")
                                {
                                    drawTitles.add(shape->m_title +
                                        L" " +
                                        FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_volDigit));
                                    drawColors.add(shape->m_color);
                                    if (shape->m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape->m_title2 +
                                           L" " +
                                            FCTran::getValueByDigit(shape->m_datas2.get(crossLineIndex), m_volDigit));
                                        drawColors.add(shape->m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint->textSize(drawTitles.get(i), getFont());
                FCRect dRect = { iLeft, candleDivHeight + 5, iLeft + tSize.cx, candleDivHeight + 5 + tSize.cy };
                paint->drawText(
                    drawTitles.get(i), drawColors.get(i), getFont(), dRect);
                iLeft += tSize.cx + 5;
            }
        }
        //上面显示数据  高开低收
        if (m_cycle == L"trend")
        {
            ArrayList<String> drawTitles;
            ArrayList<Long> drawColors;
if((int)m_text.length() > 0){
                drawTitles.add(m_text);
                drawColors.add(getTextColor());
            }
            drawTitles.add((String)L"CLOSE " +
                FCTran::getValueByDigit(m_data.get(crossLineIndex).m_close, m_candleDigit));
            drawColors.add(getTextColor());
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape *shape = m_shapes.get(i);
                    if (shape->m_divIndex == 0)
                    {
                        if ((int)shape->m_title.length() > 0)
                        {
                            if (shape->m_shapeType == L"bar" && shape->m_style == L"2color")
                            {
                                drawTitles.add(shape->m_title +
                                    L" " +
                                    FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_candleDigit));
                                drawColors.add(shape->m_color2);
                            }
                            else
                            {
                                if (shape->m_shapeType != L"text")
                                {
                                    drawTitles.add(shape->m_title +
                                        L" " +
                                        FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_candleDigit));
                                    drawColors.add(shape->m_color);
                                    if (shape->m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape->m_title2 +
                                            L" " +
                                            FCTran::getValueByDigit(shape->m_datas2.get(crossLineIndex), m_candleDigit));
                                        drawColors.add(shape->m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint->textSize(drawTitles.get(i), getFont());
                FCRect dRect = { iLeft, 5, iLeft + tSize.cx, 5 + tSize.cy };
                paint->drawText(drawTitles.get(i), drawColors.get(i), getFont(), dRect);
                iLeft += tSize.cx + 5;
            }
        }
        else
        {
            ArrayList<String> drawTitles;
            ArrayList<Long> drawColors;
if((int)m_text.length() > 0){
                drawTitles.add(m_text);
                drawColors.add(getTextColor());
            }
            if (m_mainIndicator == L"MA")
            {
                if (m_ma5.size() > 0)
                {
                    drawTitles.add((String)L"MA5 " +
                        FCTran::getValueByDigit(m_ma5.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MA5");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_ma10.size() > 0)
                {
                    drawTitles.add((String)L"MA10 " +
                        FCTran::getValueByDigit(m_ma10.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MA10");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_ma20.size() > 0)
                {
                    drawTitles.add((String)L"MA20 " +
                        FCTran::getValueByDigit(m_ma20.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MA20");
                }
                drawColors.add(m_indicatorColors.get(2));
                if (m_ma30.size() > 0)
                {
                    drawTitles.add((String)L"MA30 " +
                        FCTran::getValueByDigit(m_ma30.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MA30");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_ma120.size() > 0)
                {
                    drawTitles.add((String)L"MA120 " +
                        FCTran::getValueByDigit(m_ma120.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MA120");
                }
                drawColors.add(m_indicatorColors.get(4));
                if (m_ma250.size() > 0)
                {
                    drawTitles.add((String)L"MA250 " +
                        FCTran::getValueByDigit(m_ma250.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MA250");
                }
                drawColors.add(m_indicatorColors.get(3));
            }
            else if (m_mainIndicator == L"BOLL")
            {
                if (m_bollMid.size() > 0)
                {
                    drawTitles.add((String)L"MID " +
                        FCTran::getValueByDigit(m_bollMid.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"MID");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_bollUp.size() > 0)
                {
                    drawTitles.add((String)L"UP " +
                        FCTran::getValueByDigit(m_bollUp.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"UP");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_bollDown.size() > 0)
                {
                    drawTitles.add((String)L"LOW " +
                        FCTran::getValueByDigit(m_bollDown.get(crossLineIndex), m_candleDigit));
                }
                else
                {
                    drawTitles.add(L"LOW");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape *shape = m_shapes.get(i);
                    if (shape->m_divIndex == 0)
                    {
                        if (shape->m_title.length() > 0)
                        {
                            if (shape->m_shapeType == L"bar" && shape->m_style == L"2color")
                            {
                                drawTitles.add(shape->m_title +
                                    L" " +
                                    FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_candleDigit));
                                drawColors.add(shape->m_color2);
                            }
                            else
                            {
                                if (shape->m_shapeType != L"text")
                                {
                                    drawTitles.add(shape->m_title +
                                        L" " +
                                        FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex)
                                            , m_candleDigit));
                                    drawColors.add(shape->m_color);
                                    if (shape->m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape->m_title2 +
                                            L" " +
                                            FCTran::getValueByDigit(shape->m_datas2.get(crossLineIndex)
                                                , m_candleDigit));
                                        drawColors.add(shape->m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint->textSize(drawTitles.get(i), getFont());
                FCRect dRect = { iLeft, 5, iLeft + tSize.cx, 5 + tSize.cy };
                paint->drawText(drawTitles.get(i), drawColors.get(i), getFont(), dRect);
                iLeft += tSize.cx + 5;
            }
        }
        if (indDivHeight > 0)
        {
            ArrayList<String> drawTitles;
            ArrayList<Long> drawColors;
            if (m_showIndicator == L"MACD")
            {
                if (m_alldifarr.size() > 0)
                {
                    drawTitles.add((String)L"DIF " +
                        FCTran::getValueByDigit(m_alldifarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"DIF");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_alldeaarr.size() > 0)
                {
                    drawTitles.add((String)L"DEA " +
                        FCTran::getValueByDigit(m_alldeaarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"DEA");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_allmacdarr.size() > 0)
                {
                    drawTitles.add((String)L"MACD " +
                        FCTran::getValueByDigit(m_allmacdarr.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"MACD");
                }
                drawColors.add(m_indicatorColors.get(4));
            }
            else if (m_showIndicator == L"KDJ")
            {
                if (m_kdjK.size() > 0)
                {
                    drawTitles.add((String)L"K " +
                        FCTran::getValueByDigit(m_kdjK.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"K");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_kdjD.size() > 0)
                {
                    drawTitles.add((String)L"D " +
                        FCTran::getValueByDigit(m_kdjD.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"D");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_kdjJ.size() > 0)
                {
                    drawTitles.add((String)L"J " +
                        FCTran::getValueByDigit(m_kdjJ.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"J");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator == L"RSI")
            {
                if (m_rsi1.size() > 0)
                {
                    drawTitles.add((String)L"RSI6 " +
                        FCTran::getValueByDigit(m_rsi1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"RSI6");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_rsi2.size() > 0)
                {
                    drawTitles.add((String)L"RSI12 " +
                        FCTran::getValueByDigit(m_rsi2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"RSI12");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_rsi3.size() > 0)
                {
                    drawTitles.add((String)L"RSI24 " +
                        FCTran::getValueByDigit(m_rsi3.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"RSI24");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator == L"BIAS")
            {
                if (m_bias1.size() > 0)
                {
                    drawTitles.add((String)L"BIAS6 " +
                        FCTran::getValueByDigit(m_bias1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"BIAS6");
                }
                drawColors.add(m_indicatorColors.get(5));
                if (m_bias2.size() > 0)
                {
                    drawTitles.add((String)L"BIAS12 " +
                        FCTran::getValueByDigit(m_bias2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add((String)L"BIAS12");
                }
                drawColors.add(m_indicatorColors.get(1));
                if (m_bias3.size() > 0)
                {
                    drawTitles.add((String)L"BIAS24 " +
                        FCTran::getValueByDigit(m_bias3.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"BIAS24");
                }
                drawColors.add(m_indicatorColors.get(2));
            }
            else if (m_showIndicator == L"ROC")
            {
                if (m_roc.size() > 0)
                {
                    drawTitles.add((String)L"ROC " +
                        FCTran::getValueByDigit(m_roc.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"ROC");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_rocMa.size() > 0)
                {
                    drawTitles.add((String)L"ROCMA " +
                        FCTran::getValueByDigit(m_rocMa.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"ROCMA");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator == L"WR")
            {
                if (m_wr1.size() > 0)
                {
                    drawTitles.add((String)L"WR5 " +
                        FCTran::getValueByDigit(m_wr1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"WR5");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_wr2.size() > 0)
                {
                    drawTitles.add((String)L"WR10 " +
                        FCTran::getValueByDigit(m_wr2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"WR10");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator == L"CCI")
            {
                if (m_cci.size() > 0)
                {
                    drawTitles.add((String)L"CCI " +
                        FCTran::getValueByDigit(m_cci.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"CCI");
                }
                drawColors.add(m_indicatorColors.get(0));
            }
            else if (m_showIndicator == L"BBI")
            {
                if (m_bbi.size() > 0)
                {
                    drawTitles.add((String)L"BBI " +
                        FCTran::getValueByDigit(m_bbi.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"BBI");
                }
                drawColors.add(m_indicatorColors.get(0));
            }
            else if (m_showIndicator == L"TRIX")
            {
                if (m_trix.size() > 0)
                {
                    drawTitles.add((String)L"TRIX " +
                        FCTran::getValueByDigit(m_trix.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"TRIX");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_trixMa.size() > 0)
                {
                    drawTitles.add((String)L"TRIXMA " +
                        FCTran::getValueByDigit(m_trixMa.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"TRIXMA");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            else if (m_showIndicator == L"DMA")
            {
                if (m_dma1.size() > 0)
                {
                    drawTitles.add((String)L"MA10 " +
                        FCTran::getValueByDigit(m_dma1.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"MA10");
                }
                drawColors.add(m_indicatorColors.get(0));
                if (m_dma2.size() > 0)
                {
                    drawTitles.add((String)L"MA50 " +
                        FCTran::getValueByDigit(m_dma2.get(crossLineIndex), m_indDigit));
                }
                else
                {
                    drawTitles.add(L"MA50");
                }
                drawColors.add(m_indicatorColors.get(1));
            }
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape *shape = m_shapes.get(i);
                    if (shape->m_divIndex == 2)
                    {
                        if (shape->m_title.length() > 0)
                        {
                            if (shape->m_shapeType == L"bar" && shape->m_style == L"2color")
                            {
                                drawTitles.add(shape->m_title +
                                    L" " +
                                    FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_indDigit));
                                drawColors.add(shape->m_color2);
                            }
                            else
                            {
                                if (shape->m_shapeType != L"text")
                                {
                                    drawTitles.add(shape->m_title +
                                        L" " +
                                        FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex)
                                            , m_indDigit));
                                    drawColors.add(shape->m_color);
                                    if (shape->m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape->m_title2 +
                                            L" " +
                                            FCTran::getValueByDigit(shape->m_datas2.get(crossLineIndex)
                                                , m_indDigit));
                                        drawColors.add(shape->m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int iLeft = m_leftVScaleWidth + 5;
            for (int i = 0; i < drawTitles.size(); i++)
            {
                FCSize tSize = paint->textSize(drawTitles.get(i), getFont());
                FCRect dRect = { iLeft,
                    candleDivHeight + volDivHeight + 5, iLeft + tSize.cx,
                    candleDivHeight + volDivHeight + 5 + tSize.cy };
                paint->drawText(drawTitles.get(i), drawColors.get(i), getFont(), dRect);
                iLeft += tSize.cx + 5;
            }
        }
        if (indDivHeight2 > 0)
        {
            ArrayList<String> drawTitles;
            ArrayList<Long> drawColors;
            if (m_shapes.size() > 0)
            {
                for (int i = 0; i < m_shapes.size(); i++)
                {
                    BaseShape *shape = m_shapes.get(i);
                    if (shape->m_divIndex == 3)
                    {
                        if (shape->m_title.length() > 0)
                        {
                            if (shape->m_shapeType == L"bar" && shape->m_style == L"2color")
                            {
                                drawTitles.add(shape->m_title +
                                    L" " +
                                    FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex), m_indDigit2));
                                drawColors.add(shape->m_color2);
                            }
                            else
                            {
                                if (shape->m_shapeType != L"text")
                                {
                                    drawTitles.add(shape->m_title +
                                        L" " +
                                        FCTran::getValueByDigit(shape->m_datas.get(crossLineIndex)
                                            , m_indDigit2));
                                    drawColors.add(shape->m_color);
                                    if (shape->m_datas2.size() > 0)
                                    {
                                        drawTitles.add(shape->m_title2 +
                                            L" " +
                                            FCTran::getValueByDigit(shape->m_datas2.get(crossLineIndex)
                                                , m_indDigit2));
                                        drawColors.add(shape->m_color2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (drawTitles.size() > 9)
            {
                int iLeft = m_leftVScaleWidth + 5;
                for (int i = 0; i < drawTitles.size(); i++)
                {
                    FCSize tSize = paint->textSize(drawTitles.get(i), getFont());
                    FCRect dRect = { iLeft,
                        candleDivHeight + volDivHeight + indDivHeight + 5 + tSize.cy / 2, iLeft + tSize.cx,
                        candleDivHeight + volDivHeight + indDivHeight + 5 + tSize.cy / 2 + tSize.cy };
                    paint->drawText(drawTitles.get(i), drawColors.get(i), getFont(), dRect);
                    iLeft += tSize.cx + 5;
                }
            }
        }

        if (m_showCrossLine)
        {
            String rightText = L"";
            if (m_touchPosition.y < candleDivHeight)
            {
                rightText = FCTran::getValueByDigit(getChartValue(m_touchPosition)
                    , m_candleDigit);
            }
            else if (m_touchPosition.y > candleDivHeight &&
                m_touchPosition.y < candleDivHeight + volDivHeight)
            {
                rightText = FCTran::getValueByDigit(getChartValue(m_touchPosition) / m_magnitude
                    , m_volDigit);
            }
            else if (m_touchPosition.y > candleDivHeight + volDivHeight &&
                m_touchPosition.y < candleDivHeight + volDivHeight + indDivHeight)
            {
                rightText = FCTran::getValueByDigit(getChartValue(m_touchPosition)
                    , m_indDigit);
            }
            else if (m_touchPosition.y >
                candleDivHeight + volDivHeight + indDivHeight &&
                m_touchPosition.y <
                candleDivHeight + volDivHeight + indDivHeight + indDivHeight2)
            {
                rightText = FCTran::getValueByDigit(getChartValue(m_touchPosition)
                    , m_indDigit2);
            }

            int drawY = m_touchPosition.y;
            if (drawY > size.cy - m_hScaleHeight)
            {
                drawY = size.cy - m_hScaleHeight;
            }
            FCSize tSize = paint->textSize(rightText, getFont());
            if (m_leftVScaleWidth > 0)
            {
                paint->fillRect(m_crossTipColor, m_leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2 - 4,
                    m_leftVScaleWidth, drawY + tSize.cy / 2 + 3);
                FCRect dRect = { m_leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2, m_leftVScaleWidth, drawY + tSize.cy / 2 };
                paint->drawText(rightText, getTextColor(), getFont(),
                    dRect);
            }
            if (m_rightVScaleWidth > 0)
            {
                paint->fillRect(m_crossTipColor, size.cx - m_rightVScaleWidth, drawY - tSize.cy / 2 - 4,
                    size.cx - m_rightVScaleWidth + tSize.cx, drawY + tSize.cy / 2 + 3);
                FCRect dRect = { size.cx - m_rightVScaleWidth, drawY - tSize.cy / 2, size.cx - m_rightVScaleWidth + tSize.cx, drawY + tSize.cy / 2 };
                paint->drawText(rightText, getTextColor(), getFont(),
                    dRect);
            }
            //绘制十字线
            int drawX = getChartX(m_crossStopIndex);
            if (m_targetOldX == 0 && m_targetOldX2 == 0)
            {
                drawX = m_touchPosition.x;
            }
            if (drawX < m_leftVScaleWidth)
            {
                drawX = m_leftVScaleWidth;
            }
            if (drawX > size.cx - m_rightVScaleWidth)
            {
                drawX = size.cx - m_rightVScaleWidth;
            }
            if (!m_sPlot && m_selectShape == L"")
            {
                paint->drawLine(m_crossLineColor, m_lineWidthChart, 0,
                    m_leftVScaleWidth, drawY, size.cx - m_rightVScaleWidth, drawY);
                paint->drawLine(m_crossLineColor, m_lineWidthChart, 0, drawX, 0,
                    drawX, size.cy - m_hScaleHeight);
            }
            if (m_crossStopIndex != -1)
            {
                double dateNum = m_data.get(m_crossStopIndex).m_date;
                String xText = FCTran::doubleToStr(dateNum);
                int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, ms = 0;
                FCTran::getDateByNum(dateNum, &year, &month, &day, &hour, &minute, &second, &ms);
                if (m_hScaleFormat.length() > 0)
                {
                    xText = FCTran::getFormatDate(m_hScaleFormat, year, month, day, hour, minute, second);
                }
                else
                {
                    if (m_cycle == L"day")
                    {
                        xText = FCTran::getFormatDate(L"yyyy-MM-dd", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"minute")
                    {
                        xText = FCTran::getFormatDate(L"yyyy-MM-dd hh:mm", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"trend")
                    {
                        xText = FCTran::getFormatDate(L"HH:mm", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"second")
                    {
                        xText = FCTran::getFormatDate(L"HH:mm:ss", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"tick")
                    {
                        xText = FCTran::intToStr(m_crossStopIndex + 1);
                    }
                }
                FCSize xSize = paint->textSize(xText, getFont());
                paint->fillRect(
                    m_crossTipColor,
                    drawX - xSize.cx / 2 - 2,
                    candleDivHeight + volDivHeight + indDivHeight,
                    drawX + xSize.cx / 2 + 2,
                    candleDivHeight + volDivHeight + indDivHeight + xSize.cy + 6);
                FCRect dRect = { drawX - xSize.cx / 2,
                    candleDivHeight + volDivHeight + indDivHeight + 3, drawX + xSize.cx / 2,
                    candleDivHeight + volDivHeight + indDivHeight + 3 + xSize.cy };
                paint->drawText(xText, getTextColor(), getFont(), dRect);
            }
        }
    }

    void FCChart::drawChartScale(FCPaint* paint, const FCRect& clipRect) {
        FCSize size = getSize();
        if (m_leftVScaleWidth > 0)
        {
            paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, 0, m_leftVScaleWidth,
                size.cy - m_hScaleHeight);
        }
        if (m_rightVScaleWidth > 0)
        {
            paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                size.cx - m_rightVScaleWidth, 0, size.cx - m_rightVScaleWidth,
                size.cy - m_hScaleHeight);
        }
        if (m_hScaleHeight > 0)
        {
            paint->drawLine(m_scaleColor, m_lineWidthChart, 0, 0,
                size.cy - m_hScaleHeight, size.cx, size.cy - m_hScaleHeight);
        }
        int candleDivHeight = getCandleDivHeight();
        int volDivHeight = getVolDivHeight();
        int indDivHeight = getIndDivHeight();
        int indDivHeight2 = getIndDivHeight2();
        if (volDivHeight > 0)
        {
            paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight, size.cx - m_rightVScaleWidth, candleDivHeight);
        }
        if (indDivHeight > 0)
        {
            paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight + volDivHeight,
                size.cx - m_rightVScaleWidth,
                candleDivHeight + volDivHeight);
        }
        if (indDivHeight2 > 0)
        {
            paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                m_leftVScaleWidth, candleDivHeight + volDivHeight + indDivHeight,
                size.cx - m_rightVScaleWidth,
                candleDivHeight + volDivHeight + indDivHeight);
        }
        if (m_data.size() > 0)
        {
            FCPoint topPoint = { 0, 20 };
            FCPoint bottomPoint = { 0, candleDivHeight - 10 };
            double candleMax = getChartValue(topPoint);
            double candleMin = getChartValue(bottomPoint);
            chartGridScale(candleMin, candleMax, (candleDivHeight - m_candlePaddingTop - m_candlePaddingBottom) / 2,
                m_vScaleDistance, m_vScaleDistance / 2,
                (candleDivHeight - m_candlePaddingTop - m_candlePaddingBottom) / m_vScaleDistance);
            if (m_gridStepChart > 0)
            {
                ArrayList<double> drawValues;
                bool isTrend = m_cycle == L"trend";
                double firstOpen = m_firstOpen;
                if (isTrend)
                {
                    if(firstOpen == 0){
                        firstOpen = m_data.get(m_firstVisibleIndex).m_close;
                    }
                    double subValue = (candleMax - candleMin);
                    int count = (candleDivHeight -
                        m_candlePaddingTop -
                        m_candlePaddingBottom) /
                        m_vScaleDistance;
                    if (count > 0)
                    {
                        subValue /= count;
                    }
                    double start = firstOpen;
                    while (start < candleMax)
                    {
                        start += subValue;
                        if (start <= candleMax)
                        {
                            drawValues.add(start);
                        }
                    }
                    start = firstOpen;
                    while (start > candleMin)
                    {
                        start -= subValue;
                        if (start >= candleMin)
                        {
                            drawValues.add(start);
                        }
                    }
                }
                else
                {
                    double start = 0;
                    if (candleMin >= 0)
                    {
                        while (start + m_gridStepChart < candleMin)
                        {
                            start += m_gridStepChart;
                        }
                    }
                    else
                    {
                        while (start - m_gridStepChart > candleMin)
                        {
                            start -= m_gridStepChart;
                        }
                    }

                    while (start <= candleMax)
                    {
                        if (start > candleMin)
                        {
                            drawValues.add(start);
                        }
                        start += m_gridStepChart;
                    }
                }
                drawValues.add(firstOpen);
                for (int i = 0; i < drawValues.size(); i++)
                {
                    double start = drawValues.get(i);
                    int hAxisY = getChartY(0, start);
                    if (hAxisY < 1 || hAxisY > candleDivHeight)
                    {
                        continue;
                    }
                    paint->drawLine(m_gridColor, m_lineWidthChart, 0,
                        m_leftVScaleWidth, hAxisY,
                        size.cx - m_rightVScaleWidth, hAxisY);
                    paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                        m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                    paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                        size.cx - m_rightVScaleWidth, hAxisY,
                        size.cx - m_rightVScaleWidth + 8, hAxisY);

                    String drawText = FCTran::getValueByDigit(start, m_candleDigit);

                    FCSize tSize = paint->textSize(drawText, getFont());
                    if (isTrend)
                    {
                        double diffRange = ((start - firstOpen) / firstOpen * 100);
                        String diffRangeStr = FCTran::getValueByDigit(diffRange, 2) + L"%";
                        FCSize dSize = paint->textSize(diffRangeStr, getFont());
                        if (diffRange >= 0)
                        {
                            FCRect dRect = { size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + dSize.cx,
                                    hAxisY + tSize.cy / 2 };
                            paint->drawText(diffRangeStr, m_upColor, getFont(),
                                dRect);
                        }
                        else
                        {
                            FCRect dRect = { size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + dSize.cx,
                                    hAxisY + tSize.cy / 2 };
                            paint->drawText(diffRangeStr, m_downColor, getFont(),
                                dRect);
                        }
                    }
                    else
                    {
                        FCRect dRect = { size.cx - m_rightVScaleWidth + 10,
                            hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                            hAxisY + tSize.cy / 2 };
                        paint->drawText(drawText, getTextColor(), getFont(), dRect);
                    }
                    FCRect ddRect = { m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2 };
                    paint->drawText(drawText, getTextColor(), getFont(),
                        ddRect);
                }
            }
            topPoint.x = 0;
            topPoint.y = candleDivHeight + 10 ;
            bottomPoint.x = 0;
            bottomPoint.y = candleDivHeight + volDivHeight - 10;
            double volMax = getChartValue(topPoint);
            double volMin = getChartValue(bottomPoint);
            chartGridScale(volMin, volMax, (volDivHeight - m_volPaddingTop - m_volPaddingBottom) / 2,
                m_vScaleDistance, m_vScaleDistance / 2,
                (volDivHeight - m_volPaddingTop - m_volPaddingBottom) / m_vScaleDistance);
            if (m_gridStepChart > 0)
            {
                double start = 0;
                if (volMin >= 0)
                {
                    while (start + m_gridStepChart < volMin)
                    {
                        start += m_gridStepChart;
                    }
                }
                else
                {
                    while (start - m_gridStepChart > volMin)
                    {
                        start -= m_gridStepChart;
                    }
                }
                while (start <= volMax)
                {
                    if (start > volMin)
                    {
                        int hAxisY = getChartY(1, start);
                        if (hAxisY < candleDivHeight ||
                            hAxisY > candleDivHeight + volDivHeight)
                        {
                            start += m_gridStepChart;
                            continue;
                        }
                        paint->drawLine(m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth,
                            hAxisY, size.cx - m_rightVScaleWidth, hAxisY);
                        paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                            m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                        paint->drawLine(m_scaleColor, m_lineWidthChart, 0, size.cx - m_rightVScaleWidth,
                            hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY);
                        String drawText =
                            FCTran::getValueByDigit(start / m_magnitude, m_volDigit);
                        FCSize tSize = paint->textSize(drawText, getFont());
                        FCRect dRect = { size.cx - m_rightVScaleWidth + 10,
                                hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                hAxisY + tSize.cy / 2 };
                        paint->drawText(drawText, getTextColor(), getFont(),
                            dRect);
                        FCRect dRect2 = { m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2 };
                        paint->drawText(drawText, getTextColor(), getFont(),
                            dRect2);
                    }
                    start += m_gridStepChart;
                }
            }
            if (indDivHeight > 0)
            {
                topPoint.x = 0;
                topPoint.y = candleDivHeight + volDivHeight + 10;
                bottomPoint.x = 0;
                bottomPoint.y = candleDivHeight + volDivHeight + indDivHeight - 10;
                double indMax = getChartValue(topPoint);
                double indMin = getChartValue(bottomPoint);
                chartGridScale(indMin, indMax, (indDivHeight - m_indPaddingTop - m_indPaddingBottom) / 2,
                    m_vScaleDistance, m_vScaleDistance / 2,
                    (indDivHeight - m_indPaddingTop - m_indPaddingBottom) / m_vScaleDistance);
                if (m_gridStepChart > 0)
                {
                    double start = 0;
                    if (indMin >= 0)
                    {
                        while (start + m_gridStepChart < indMin)
                        {
                            start += m_gridStepChart;
                        }
                    }
                    else
                    {
                        while (start - m_gridStepChart > indMin)
                        {
                            start -= m_gridStepChart;
                        }
                    }

                    while (start <= indMax)
                    {
                        if (start > indMin)
                        {
                            int hAxisY = getChartY(2, start);
                            if (hAxisY < candleDivHeight + volDivHeight ||
                                hAxisY > candleDivHeight + volDivHeight + indDivHeight)
                            {
                                start += m_gridStepChart;
                                continue;
                            }
                            paint->drawLine(m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth, hAxisY);
                            paint->drawLine(m_scaleColor, m_lineWidthChart, 0, m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                            paint->drawLine(m_scaleColor, m_lineWidthChart, 0,
                                size.cx - m_rightVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY);
                            String drawText = FCTran::getValueByDigit(start, m_indDigit);
                            FCSize tSize = paint->textSize(drawText, getFont());
                            FCRect dRect = { size.cx - m_rightVScaleWidth + 10,
                                    hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx,
                                    hAxisY + tSize.cy / 2 };
                            paint->drawText(drawText, getTextColor(), getFont(),
                                dRect);
                            FCRect dRect2 = { m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2 };
                            paint->drawText(drawText, getTextColor(), getFont(),
                                dRect2);
                        }
                        start += m_gridStepChart;
                    }
                }
            }
            if (indDivHeight2 > 0)
            {
                topPoint.x = 0;
                topPoint.y = candleDivHeight + volDivHeight + indDivHeight + 10;
                bottomPoint.x = 0;
                bottomPoint.y = candleDivHeight + volDivHeight + indDivHeight + indDivHeight2 - 10;
                double indMax2 = getChartValue(topPoint);
                double indMin2 = getChartValue(bottomPoint);
                chartGridScale(indMin2, indMax2, (indDivHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) / 2, m_vScaleDistance, m_vScaleDistance / 2, (indDivHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) /
                    m_vScaleDistance);
                if (m_gridStepChart > 0)
                {
                    double start = 0;
                    if (indMin2 >= 0)
                    {
                        while (start + m_gridStepChart < indMin2)
                        {
                            start += m_gridStepChart;
                        }
                    }
                    else
                    {
                        while (start - m_gridStepChart > indMin2)
                        {
                            start -= m_gridStepChart;
                        }
                    }

                    while (start <= indMax2)
                    {
                        if (start > indMin2)
                        {
                            int hAxisY = getChartY(3, start);
                            if (hAxisY < candleDivHeight + volDivHeight + indDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight + indDivHeight2)
                            {
                                start += m_gridStepChart;
                                continue;
                            }
                            paint->drawLine(m_gridColor, m_lineWidthChart, 0, m_leftVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth, hAxisY);
                            paint->drawLine(m_scaleColor, m_lineWidthChart, 0, m_leftVScaleWidth - 8, hAxisY, m_leftVScaleWidth, hAxisY);
                            paint->drawLine(m_scaleColor, m_lineWidthChart, 0, size.cx - m_rightVScaleWidth, hAxisY, size.cx - m_rightVScaleWidth + 8, hAxisY);
                            String drawText = FCTran::getValueByDigit(start, m_indDigit);
                            FCSize tSize = paint->textSize(drawText, getFont());
                            FCRect dRect = { size.cx - m_rightVScaleWidth + 10, hAxisY - tSize.cy / 2, size.cx - m_rightVScaleWidth + 10 + tSize.cx, hAxisY + tSize.cy / 2 };
                            paint->drawText(drawText, getTextColor(), getFont(), dRect);
                            FCRect dRect2 = { m_leftVScaleWidth - tSize.cx - 10, hAxisY - tSize.cy / 2, m_leftVScaleWidth - 10, hAxisY + tSize.cy / 2 };
                            paint->drawText(drawText, getTextColor(), getFont(),
                                dRect2);
                        }
                        start += m_gridStepChart;
                    }
                }
            }
        }
        if (m_data.size() > 0 && m_hScaleHeight > 0)
        {
            double dLeft = m_leftVScaleWidth + 10;
            for (int i = m_firstVisibleIndex; i <= m_lastVisibleIndex; i++)
            {
                double dateNum = m_data.get(i).m_date;
                String xText = FCTran::doubleToStr(dateNum);
                int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, ms = 0;
                FCTran::getDateByNum(dateNum, &year, &month, &day, &hour, &minute, &second, &ms);
                if (m_hScaleFormat.length() > 0)
                {
                    xText = FCTran::getFormatDate(m_hScaleFormat, year, month, day, hour, minute, second);
                }
                else
                {
                    if (m_cycle == L"day")
                    {
                        xText = FCTran::getFormatDate(L"yyyy-MM-dd", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"minute")
                    {
                        xText = FCTran::getFormatDate(L"yyyy-MM-dd hh:mm", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"trend")
                    {
                        xText = FCTran::getFormatDate(L"HH:mm", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"second")
                    {
                        xText = FCTran::getFormatDate(L"HH:mm:ss", year, month, day, hour, minute, second);
                    }
                    else if (m_cycle == L"tick")
                    {
                        xText = FCTran::intToStr(m_crossStopIndex + 1);
                    }
                }
                FCSize tSize = paint->textSize(xText, getFont());
                int x = getChartX(i);
                int dx = x - tSize.cx / 2;
                if (dx > dLeft && dx < size.cx - m_rightVScaleWidth - 10)
                {
                    paint->drawLine(m_scaleColor, m_lineWidthChart, 0, x, size.cy - m_hScaleHeight, x, size.cy - m_hScaleHeight + 8);
                    FCRect dRect = { dx, size.cy - m_hScaleHeight + 8 - tSize.cy / 2 + 7, dx + tSize.cx, size.cy - m_hScaleHeight + 8 + tSize.cy / 2 + 7 };
                    paint->drawText(xText, getTextColor(), getFont(), dRect);
                    i = i + (int)((tSize.cx + m_hScaleTextDistance) / m_hScalePixel) + 1;
                }
            }
        }
    }

    void FCChart::ellipseOR(double x1, double y1, double x2, double y2, double x3, double y3) {
        m_oXChart = ((y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1) +
            (y2 - y1) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3)) /
            (2 * (x2 - x1) * (y3 - y1) - 2 * (x3 - x1) * (y2 - y1));
        m_oYChart = ((x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) +
            (x2 - x1) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3)) /
            (2 * (y2 - y1) * (x3 - x1) - 2 * (y3 - y1) * (x2 - x1));
        m_rChart = sqrt((x1 - m_oXChart) * (x1 - m_oXChart) + (y1 - m_oYChart) * (y1 - m_oYChart));
    }

    bool FCChart::ellipseHasPoint(double x, double y, double oX, double oY, double a, double b) {
        x -= oX;
        y -= oY;
        if (a == 0 && b == 0 && x == 0 && y == 0)
        {
            return true;
        }
        if (a == 0)
        {
            if (x == 0 && y >= -b && y <= b)
            {
                return false;
            }
        }
        if (b == 0)
        {
            if (y == 0 && x >= -a && x <= a)
            {
                return true;
            }
        }
        if ((x * x) / (a * a) + (y * y) / (b * b) >= 0.8 &&
            (x * x) / (a * a) + (y * y) / (b * b) <= 1.2)
        {
            return true;
        }
        return false;
    }

    int FCChart::fibonacciValue(int index) {
        if (index < 1)
        {
            return 0;
        }
        else
        {
            ArrayList<int> vList;
            for (int i = 0; i < index; i++)
            {
                vList.add(0);
            }
            int result = 0;
            for (int i = 0; i <= index - 1; i++)
            {
                if (i == 0 || i == 1)
                {
                    vList.set(i, 1);
                }
                else
                {
                    vList.set(i, vList.get(i - 1) + vList.get(i - 2));
                }
            }
            result = vList.get(index - 1);
            return result;
        }
    }

    String FCChart::getViewType() {
        return L"Chart";
    }

    void FCChart::getCandleRange(FCPlot* plot) {
        int bIndex = getChartIndexByDate(plot->m_key1);
        int eIndex = getChartIndexByDate(plot->m_key2);
        int tempBIndex = bIndex > eIndex ? eIndex : bIndex;
        int tempEIndex = bIndex > eIndex ? bIndex : eIndex;
        bIndex = tempBIndex;
        eIndex = tempEIndex;
        ArrayList<double> highList;
        ArrayList<double> lowList;
        for (int i = bIndex; i <= eIndex; i++)
        {
            highList.add(m_data.get(i).m_high);
            lowList.add(m_data.get(i).m_low);
        }
        m_nHighChart = maxValue(&highList);
        m_nLowChart = minValue(&lowList);
    }

    double FCChart::getEMA(int n, double value, double lastEMA) {
        return (value * 2 + lastEMA * (n - 1)) / (n + 1);
    }

    ArrayList<double> FCChart::getMACD(ArrayList<double>* dif, ArrayList<double>* dea) {
        ArrayList<double> result;
        for (int i = 0; i < dif->size(); i++)
        {
            result.add((dif->get(i) - dea->get(i)) * 2);
        }
        return result;
    }

    ArrayList<double> FCChart::getDIF(ArrayList<double>* close12, ArrayList<double>* close26) {
        ArrayList<double> result;
        for (int i = 0; i < close12->size(); i++)
        {
            result.add(close12->get(i) - close26->get(i));
        }
        return result;
    }

    int FCChart::getChartIndexByDate(double date) {
        int index = -1;
        for (int i = 0; i < m_data.size(); i++)
        {
            if (m_data.get(i).m_date == date)
            {
                index = i;
                break;
            }
        }
        return index;
    }

    ArrayList<int> FCChart::getPercentParams(double y1, double y2) {
        double y0 = 0, y25 = 0, y50 = 0, y75 = 0, y100 = 0;
        y0 = y1;
        y25 = y1 <= y2 ? y1 + (y2 - y1) / 4 : y2 + (y1 - y2) * 3 / 4;
        y50 = y1 <= y2 ? y1 + (y2 - y1) / 2 : y2 + (y1 - y2) / 2;
        y75 = y1 <= y2 ? y1 + (y2 - y1) * 3 / 4 : y2 + (y1 - y2) / 4;
        y100 = y2;
        ArrayList<int> list;
        list.add((int)y0);
        list.add((int)y25);
        list.add((int)y50);
        list.add((int)y75);
        list.add((int)y100);
        return list;
    }

    void FCChart::getTRIXData(ArrayList<double>* ticks, int m, ArrayList<double>* trixArr, ArrayList<double>* matrixArr) {
        int length = ticks->size();
        ArrayList<double> mtrArr;
        ArrayList<double> emaArr1;
        emaArr1.add(ticks->get(0));
        for (int i = 1; i < length; i++)
        {
            emaArr1.add(getEMA(m, ticks->get(i), emaArr1.get(i - 1)));
        }

        ArrayList<double> emaArr2;
        emaArr2.add(emaArr1.get(0));
        for (int i = 1; i < length; i++)
        {
            emaArr2.add(getEMA(m, emaArr1.get(i), emaArr2.get(i - 1)));
        }

        mtrArr.add(emaArr2.get(0));
        for (int i = 1; i < length; i++)
        {
            mtrArr.add(getEMA(m, emaArr2.get(i), mtrArr.get(i - 1)));
        }

        ArrayList<double> refV = refValue(&mtrArr, 1);
        for (int i = 0; i < length; i++)
        {
            double trix = 100 * (mtrArr.get(i) - refV.get(i)) / refV.get(i);
            trixArr->add(trix);
        }

        ArrayList<double> matrixArrCopy = maValue(trixArr, m);
        for (int i = 0; i < matrixArrCopy.size(); i++)
        {
            matrixArr->add(matrixArrCopy.get(i));
        }
    }

    void FCChart::getBollData(ArrayList<double>* ticks, int maDays, ArrayList<double>* ups, ArrayList<double>* mas, ArrayList<double>* lows) {
        int tickBegin = maDays - 1;
        double maSum = 0;
        double p = 0;
        for (int i = 0; i < ticks->size(); i++)
        {
            double c = ticks->get(i);
            double ma = 0;
            double md = 0;
            int bstart = 0;
            double mdSum = 0;
            maSum = maSum + c;
            if (i >= tickBegin)
            {
                maSum = maSum - p;
                ma = maSum / maDays;
                bstart = i - tickBegin;
                p = ticks->get(bstart);
                mas->add(ma);
                bstart = i - tickBegin;
                p = ticks->get(bstart);
                ArrayList<double> values;
                for (int j = bstart; j < bstart + maDays; j++)
                {
                    values.add(ticks->get(j));
                }
                mdSum = standardDeviationSum(&values, ma);
                md = sqrt(mdSum / maDays);
                ups->add(ma + 2 * md);
                lows->add(ma - 2 * md);
            }
            else
            {
                ma = maSum / (i + 1);
                mas->add(ma);
                ArrayList<double> values;
                for (int j = 0; j < i + 1; j++)
                {
                    values.add(ticks->get(j));
                }
                mdSum = standardDeviationSum(&values, ma);
                md = sqrt(mdSum / (i + 1));
                ups->add(ma + 2 * md);
                lows->add(ma - 2 * md);
            }
        }
    }

    void FCChart::getKDJData(ArrayList<double>* highArr, ArrayList<double>* lowArr, ArrayList<double>* closeArr, int n, int m1, int m2, ArrayList<double>* ks, ArrayList<double>* ds, ArrayList<double>* js) {
        ArrayList<double> rsvs;
        double lastK = 0;
        double lastD = 0;
        double curK = 0;
        double curD = 0;
        for (int i = 0; i < closeArr->size(); i++)
        {
            ArrayList<double> highList;
            ArrayList<double> lowList;
            int startIndex = i - n;
            if (startIndex < 0)
            {
                startIndex = 0;
            }

            for (int j = startIndex; j <= i; j++)
            {
                highList.add(highArr->get(j));
                lowList.add(lowArr->get(j));
            }

            double close = closeArr->get(i);
            double maxHigh = 0, minLow = 0;
            for (int m = 0; m < highList.size(); m++)
            {
                double high = highList.get(m);
                double low = lowList.get(m);
                if (high > maxHigh)
                {
                    maxHigh = high;
                }
                if (low < minLow)
                {
                    minLow = low;
                }
            }
            if (maxHigh == minLow)
            {
                rsvs.add(0);
            }
            else
            {
                rsvs.add(100 * (close - minLow) / (maxHigh - minLow));
            }
            if (i == 0)
            {
                lastK = rsvs.get(i);
                lastD = rsvs.get(i);
            }
            curK = lastK * (m1 - 1) / m1 + 1.0 / m1 * rsvs.get(i);
            ks->add(curK);
            lastK = curK;

            curD = lastD * (m2 - 1) / m2 + 1.0 / m2 * curK;
            ds->add(curD);
            lastD = curD;

            js->add(3.0 * curK - 2.0 * curD);
        }
    }

    void FCChart::getRSIData(ArrayList<double>* ticks, int n1, int n2, int n3, ArrayList<double>* rsi1, ArrayList<double>* rsi2, ArrayList<double>* rsi3) {
        double lastClosePx = ticks->get(0);
        double lastSm1 = 0;
        double lastSa1 = 0;
        double lastSm2 = 0;
        double lastSa2 = 0;
        double lastSm3 = 0;
        double lastSa3 = 0;
        for (int i = 0; i < ticks->size(); i++)
        {
            double c = ticks->get(i);
            double m = c - lastClosePx > 0 ? c - lastClosePx : 0;
            double a = c - lastClosePx > 0 ? c - lastClosePx : lastClosePx - c;
            if (i == 0)
            {
                lastSm1 = 0;
                lastSa1 = 0;
                rsi1->add(0);
            }
            else
            {
                lastSm1 = (m + (n1 - 1) * lastSm1) / n1;
                lastSa1 = (a + (n1 - 1) * lastSa1) / n1;
                if (lastSa1 != 0)
                {
                    rsi1->add(lastSm1 / lastSa1 * 100);
                }
                else
                {
                    rsi1->add(0);
                }
            }
            if (i == 0)
            {
                lastSm2 = 0;
                lastSa2 = 0;
                rsi2->add(0);
            }
            else
            {
                lastSm2 = (m + (n2 - 1) * lastSm2) / n2;
                lastSa2 = (a + (n2 - 1) * lastSa2) / n2;
                if (lastSa2 != 0)
                {
                    rsi2->add(lastSm2 / lastSa2 * 100);
                }
                else
                {
                    rsi2->add(0);
                }
            }
            if (i == 0)
            {
                lastSm3 = 0;
                lastSa3 = 0;
                rsi3->add(0);
            }
            else
            {
                lastSm3 = (m + (n3 - 1) * lastSm3) / n3;
                lastSa3 = (a + (n3 - 1) * lastSa3) / n3;
                if (lastSa3 != 0)
                {
                    rsi3->add(lastSm3 / lastSa3 * 100);
                }
                else
                {
                    rsi3->add(0.0);
                }
            }
            lastClosePx = c;
        }
    }

    void FCChart::getRocData(ArrayList<double>* ticks, int n, int m, ArrayList<double>* roc, ArrayList<double>* maroc) {
        for (int i = 0; i < ticks->size(); i++)
        {
            double currRoc = 0;
            if (i >= n)
            {
                currRoc = 100 * (ticks->get(i) - ticks->get(i - n)) / ticks->get(i - n);
                roc->add(currRoc);
            }
            else
            {
                currRoc = 100 * (ticks->get(i) - ticks->get(0)) / ticks->get(0);
                roc->add(currRoc);
            }
        }
        ArrayList<double> marocMA = maValue(roc, m);
        for (int i = 0; i < marocMA.size(); i++)
        {
            maroc->add(marocMA.get(i));
        }
    }

    void FCChart::getBIASData(ArrayList<double>* ticks, int n1, int n2, int n3, ArrayList<double>* bias1Arr, ArrayList<double>* bias2Arr, ArrayList<double>* bias3Arr) {
        ArrayList<double> ma1 = maValue(ticks, n1);
        ArrayList<double> ma2 = maValue(ticks, n2);
        ArrayList<double> ma3 = maValue(ticks, n3);
        for (int i = 0; i < ticks->size(); i++)
        {
            double b1 = (ticks->get(i) - ma1.get(i)) / ma1.get(i) * 100;
            double b2 = (ticks->get(i) - ma2.get(i)) / ma2.get(i) * 100;
            double b3 = (ticks->get(i) - ma3.get(i)) / ma3.get(i) * 100;
            bias1Arr->add(b1);
            bias2Arr->add(b2);
            bias3Arr->add(b3);
        }
    }

    void FCChart::getDMAData(ArrayList<double>* ticks, int n1, int n2, ArrayList<double>* difArr, ArrayList<double>* difmaArr) {
        ArrayList<double> ma10 = maValue(ticks, n1);
        ArrayList<double> ma50 = maValue(ticks, n2);
        for (int i = 0; i < ticks->size(); i++)
        {
            double dif = ma10.get(i) - ma50.get(i);
            difArr->add(dif);
        }
        ArrayList<double> difma = maValue(difArr, n1);
        for (int i = 0; i < difma.size(); i++)
        {
            difmaArr->add(difma.get(i));
        }
    }

    void FCChart::getBBIData(ArrayList<double>* ticks, int n1, int n2, int n3, int n4, ArrayList<double>* bbiArr) {
        ArrayList<double> ma3 = maValue(ticks, n1);
        ArrayList<double> ma6 = maValue(ticks, n2);
        ArrayList<double> ma12 = maValue(ticks, n3);
        ArrayList<double> ma24 = maValue(ticks, n4);
        for (int i = 0; i < ticks->size(); i++)
        {
            double bbi = (ma3.get(i) + ma6.get(i) + ma12.get(i) + ma24.get(i)) / 4;
            bbiArr->add(bbi);
        }
    }

    void FCChart::getWRData(ArrayList<double>* highArr, ArrayList<double>* lowArr, ArrayList<double>* closeArr, int n1, int n2, ArrayList<double>* wr1Arr, ArrayList<double>* wr2Arr) {
        ArrayList<double> highArr1 = hhvValue(highArr, n1);
        ArrayList<double> highArr2 = hhvValue(highArr, n2);
        ArrayList<double> lowArr1 = llvValue(lowArr, n1);
        ArrayList<double> lowArr2 = llvValue(lowArr, n2);
        for (int i = 0; i < closeArr->size(); i++)
        {
            double high1 = highArr1.get(i);
            double low1 = lowArr1.get(i);
            double high2 = highArr2.get(i);
            double low2 = lowArr2.get(i);
            double close = closeArr->get(i);
            double wr1 = 100 * (high1 - close) / (high1 - low1);
            double wr2 = 100 * (high2 - close) / (high2 - low2);
            wr1Arr->add(wr1);
            wr2Arr->add(wr2);
        }
    }

    void FCChart::getCCIData(ArrayList<double>* highArr, ArrayList<double>* lowArr, ArrayList<double>* closeArr, int n, ArrayList<double>* cciArr) {
        ArrayList<double> tpArr;
        for (int i = 0; i < closeArr->size(); i++)
        {
            tpArr.add((closeArr->get(i) + highArr->get(i) + lowArr->get(i)) / 3);
        }
        ArrayList<double> maClose = maValue(closeArr, n);

        ArrayList<double> mdArr;
        for (int i = 0; i < closeArr->size(); i++)
        {
            mdArr.add(maClose.get(i) - closeArr->get(i));
        }
        ArrayList<double> maMD = maValue(&mdArr, n);
        for (int i = 0; i < closeArr->size(); i++)
        {
            double cci = 0;
            if (maMD.get(i) > 0)
            {
                cci = (tpArr.get(i) - maClose.get(i)) / (maMD.get(i) * 0.015);
            }
            cciArr->add(cci);
        }
    }

    int FCChart::getChartX(int index) {
        return (int)(m_leftVScaleWidth +
            (index - m_firstVisibleIndex) * m_hScalePixel +
            m_hScalePixel / 2 + m_offsetX);
    }

    int FCChart::getChartMaxVisibleCount(double hScalePixel, double pureH) {
        int count = (int)((pureH - hScalePixel) / hScalePixel);
        if (count < 0)
        {
            count = 0;
        }
        return count;
    }

    int FCChart::getCandleDivHeight() {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_candleDivPercent);
        }
        else
        {
            return 0;
        }
    }

    int FCChart::getVolDivHeight() {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_volDivPercent);
        }
        else
        {
            return 0;
        }
    }

    int FCChart::getIndDivHeight() {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_indDivPercent);
        }
        else
        {
            return 0;
        }
    }

    int FCChart::getIndDivHeight2() {
        int height = getSize().cy - m_hScaleHeight;
        if (height > 0)
        {
            return (int)(height * m_indDivPercent2);
        }
        else
        {
            return 0;
        }
    }

    int FCChart::getChartWorkAreaWidth() {
        return getSize().cx - m_leftVScaleWidth - m_rightVScaleWidth - m_rightSpace - (int)m_offsetX;
    }

    void FCChart::getLRBandRange(FCPlot* plot, double a, double b) {
        int bIndex = getChartIndexByDate(plot->m_key1);
        int eIndex = getChartIndexByDate(plot->m_key2);
        int tempBIndex = bIndex > eIndex ? eIndex : bIndex;
        int tempEIndex = bIndex > eIndex ? bIndex : eIndex;
        bIndex = tempBIndex;
        eIndex = tempEIndex;
        ArrayList<double> upList;
        ArrayList<double> downList;
        for (int i = bIndex; i <= eIndex; i++)
        {
            double high = m_data.get(i).m_high;
            double low = m_data.get(i).m_low;
            double midValue = (i - bIndex + 1) * a + b;
            upList.add(high - midValue);
            downList.add(midValue - low);
        }
        m_upSubValue = maxValue(&upList);
        m_downSubValue = maxValue(&downList);
    }

    int FCChart::getChartY(int divIndex, double value) {
        if (divIndex == 0)
        {
            if (m_candleMax > m_candleMin)
            {
                double cValue = value, cMax = m_candleMax, cMin = m_candleMin;
                if (m_vScaleType != L"standard")
                {
                    if (cValue > 0)
                    {
                        cValue = log(cValue);
                    }
                    else if (cValue < 0)
                    {
                        cValue = -log(abs(cValue));
                    }
                    if (cMax > 0)
                    {
                        cMax = log(cMax);
                    }
                    else if (cMax < 0)
                    {
                        cMax = -log(abs(cMax));
                    }
                    if (cMin > 0)
                    {
                        cMin = log(cMin);
                    }
                    else if (cMin < 0)
                    {
                        cMin = -log(abs(cMin));
                    }
                }
                double rate = (cValue - cMin) / (cMax - cMin);
                int divHeight = getCandleDivHeight();
                return (int)(divHeight - m_candlePaddingBottom - (divHeight - m_candlePaddingTop - m_candlePaddingBottom) *
                    rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 1)
        {
            if (m_volMax > m_volMin)
            {
                double rate = (value - m_volMin) / (m_volMax - m_volMin);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                return (int)(candleHeight + volHeight - m_volPaddingBottom - (volHeight - m_volPaddingTop - m_volPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 2)
        {
            if (m_indMax > m_indMin)
            {
                double rate = (value - m_indMin) / (m_indMax - m_indMin);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                return (int)(candleHeight + volHeight + indHeight - m_indPaddingBottom - (indHeight - m_indPaddingTop - m_indPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 3)
        {
            if (m_indMax2 > m_indMin2)
            {
                double rate = (value - m_indMin2) / (m_indMax2 - m_indMin2);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                int indHeight2 = getIndDivHeight2();
                return (int)(candleHeight + volHeight + indHeight + indHeight2 - m_indPaddingBottom2 - (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) * rate);
            }
            else
            {
                return 0;
            }
        }
        return 0;
    }

    int FCChart::getChartIndex(const FCPoint& mp) {
        if (m_data.size() == 0)
        {
            return -1;
        }
        if (mp.x <= 0)
        {
            return 0;
        }
        double intX = mp.x - m_leftVScaleWidth - m_hScalePixel - m_offsetX;
        if(intX < 0){
            intX = 0;
        }
        int index = (int)(m_firstVisibleIndex + intX / m_hScalePixel);
        int intPixel = (int)m_hScalePixel;
        if (intPixel > 0 && (int)intX % intPixel != 0)
        {
            index++;
        }
        if (index < 0)
        {
            index = 0;
        }
        else if (index > m_data.size() - 1)
        {
            index = m_data.size() - 1;
        }
        return index;
    }

    double FCChart::getChartDateByIndex(int index) {
        double date = 0;
        if (index >= 0 && index < m_data.size())
        {
            date = m_data.get(index).m_date;
        }
        return date;
    }

    double FCChart::getChartValue(const FCPoint& point) {
        double candleHeight = getCandleDivHeight();
        double volHeight = getVolDivHeight();
        double indHeight = getIndDivHeight();
        double indHeight2 = getIndDivHeight();
        if (point.y <= candleHeight)
        {
            if(candleHeight - m_candlePaddingTop - m_candlePaddingBottom > 0){
                double rate = (candleHeight - m_candlePaddingBottom - point.y) /
                    (candleHeight - m_candlePaddingTop - m_candlePaddingBottom);
                double cMin = m_candleMin, cMax = m_candleMax;
                if (m_vScaleType != L"standard")
                {
                    if (cMax > 0)
                    {
                        cMax = log(cMax);
                    }
                    else if (cMax < 0)
                    {
                        cMax = -log(abs(cMax));
                    }
                    if (cMin > 0)
                    {
                        cMin = log(cMin);
                    }
                    else if (cMin < 0)
                    {
                        cMin = -log(abs(cMin));
                    }
                }
                double result = cMin + (cMax - cMin) * rate;
                if (m_vScaleType != L"standard")
                {
                    return pow(10, result);
                }
                else
                {
                    return result;
                }
            }
        }
        else if (point.y > candleHeight && point.y <= candleHeight + volHeight)
        {
            if(volHeight - m_volPaddingTop - m_volPaddingBottom > 0){
                double rate =
                    (volHeight - m_volPaddingBottom - (point.y - candleHeight)) /
                    (volHeight - m_volPaddingTop - m_volPaddingBottom);
                return m_volMin + (m_volMax - m_volMin) * rate;
            }
        }
        else if (point.y > candleHeight + volHeight &&
            point.y <= candleHeight + volHeight + indHeight)
        {
            if(indHeight - m_indPaddingTop - m_indPaddingBottom > 0){
                double rate = (indHeight -
                    m_indPaddingBottom -
                    (point.y - candleHeight - volHeight)) /
                    (indHeight - m_indPaddingTop - m_indPaddingBottom);
                return m_indMin + (m_indMax - m_indMin) * rate;
            }
        }
        else if (point.y > candleHeight + volHeight + indHeight &&
            point.y <= candleHeight + volHeight + indHeight + indHeight2)
        {
            if(indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2 > 0){
                double rate = (indHeight2 -
                    m_indPaddingBottom2 -
                    (point.y - candleHeight - volHeight - indHeight)) /
                    (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2);
                return m_indMin2 + (m_indMax2 - m_indMin2) * rate;
            }
        }
        return 0;
    }

    int FCChart::getChartYInRight(int divIndex, double value) {
        if (divIndex == 0)
        {
            if (m_candleMaxRight > m_candleMinRight)
            {
                double cValue = value,
                    cMax = m_candleMaxRight,
                    cMin = m_candleMinRight;
                if (m_vScaleType != L"standard")
                {
                    if (cValue > 0)
                    {
                        cValue = log(cValue);
                    }
                    else if (cValue < 0)
                    {
                        cValue = -log(abs(cValue));
                    }
                    if (cMax > 0)
                    {
                        cMax = log(cMax);
                    }
                    else if (cMax < 0)
                    {
                        cMax = -log(abs(cMax));
                    }
                    if (cMin > 0)
                    {
                        cMin = log(cMin);
                    }
                    else if (cMin < 0)
                    {
                        cMin = -log(abs(cMin));
                    }
                }
                double rate = (cValue - cMin) / (cMax - cMin);
                int divHeight = getCandleDivHeight();
                return (int)(divHeight - m_candlePaddingBottom - (divHeight - m_candlePaddingTop - m_candlePaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 1)
        {
            if (m_volMaxRight > m_volMinRight)
            {
                double rate = (value - m_volMinRight) / (m_volMaxRight - m_volMinRight);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                return (int)(candleHeight + volHeight - m_volPaddingBottom - (volHeight - m_volPaddingTop - m_volPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 2)
        {
            if (m_indMaxRight > m_indMinRight)
            {
                double rate = (value - m_indMinRight) / (m_indMaxRight - m_indMinRight);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                return (int)(candleHeight + volHeight + indHeight - m_indPaddingBottom - (indHeight - m_indPaddingTop - m_indPaddingBottom) * rate);
            }
            else
            {
                return 0;
            }
        }
        else if (divIndex == 3)
        {
            if (m_indMax2Right > m_indMin2Right)
            {
                double rate = (value - m_indMin2Right) / (m_indMax2Right - m_indMin2Right);
                int candleHeight = getCandleDivHeight();
                int volHeight = getVolDivHeight();
                int indHeight = getIndDivHeight();
                int indHeight2 = getIndDivHeight2();
                return (int)(candleHeight + volHeight + indHeight + indHeight2 - m_indPaddingBottom2 - (indHeight2 - m_indPaddingTop2 - m_indPaddingBottom2) * rate);
            }
            else
            {
                return 0;
            }
        }
        return 0;
    }

    double FCChart::getCandleDivValue(const FCPoint& point) {
        double candleHeight = getCandleDivHeight();
        double rate = 0;
        if(candleHeight - m_candlePaddingTop - m_candlePaddingBottom > 0){
            rate = (candleHeight - m_candlePaddingBottom - point.y) /
                (candleHeight - m_candlePaddingTop - m_candlePaddingBottom);
        }
        double cMin = m_candleMin, cMax = m_candleMax;
        if (m_vScaleType != L"standard")
        {
            if (cMax > 0)
            {
                cMax = log(cMax);
            }
            else if (cMax < 0)
            {
                cMax = -log(abs(cMax));
            }
            if (cMin > 0)
            {
                cMin = log(cMin);
            }
            else if (cMin < 0)
            {
                cMin = -log(abs(cMin));
            }
        }
        double result = cMin + (cMax - cMin) * rate;
        if (m_vScaleType != L"standard")
        {
            return pow(10, result);
        }
        else
        {
            return result;
        }
    }

    ArrayList<double> FCChart::hhvValue(ArrayList<double>* ticks, int days) {
        ArrayList<double> hhv;
        double max = ticks->get(0);
        for (int i = 0; i < ticks->size(); i++)
        {
            if (i >= days)
            {
                max = ticks->get(i);
                for (int j = i; j > i - days; j--)
                {
                    if (max < ticks->get(j))
                    {
                        max = ticks->get(j);
                    }
                }
                hhv.add(max);
            }
            else
            {
                if (max < ticks->get(i))
                {
                    max = ticks->get(i);
                }
                hhv.add(max);
            }
        }
        return hhv;
    }

    void FCChart::judgeSelectShape(const FCPoint& mp) {
        m_selectShape = L"";
        m_selectShapeEx = L"";
        double candleHeight = getCandleDivHeight();
        double volHeight = getVolDivHeight();
        double indHeight = getIndDivHeight();
        int index = getChartIndex(mp);
        if (mp.y >= candleHeight + volHeight &&
            mp.y <= candleHeight + volHeight + indHeight)
        {
            if (m_showIndicator == L"MACD")
            {
                if (selectLines(mp, 2, &m_allmacdarr, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"MACD";
                }
                if (selectLines(mp, 2, &m_alldifarr, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"DIF";
                }
                else if (selectLines(mp, 2, &m_alldeaarr, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"DEA";
                }
            }
            else if (m_showIndicator == L"KDJ")
            {
                if (selectLines(mp, 2, &m_kdjK, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"K";
                }
                else if (selectLines(mp, 2, &m_kdjD, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"D";
                }
                else if (selectLines(mp, 2, &m_kdjJ, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"J";
                }
            }
            else if (m_showIndicator == L"RSI")
            {
                if (selectLines(mp, 2, &m_rsi1, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"6";
                }
                else if (selectLines(mp, 2, &m_rsi2, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"12";
                }
                else if (selectLines(mp, 2, &m_rsi3, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"24";
                }
            }
            else if (m_showIndicator == L"BIAS")
            {
                if (selectLines(mp, 2, &m_bias1, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"1";
                }
                else if (selectLines(mp, 2, &m_bias2, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"2";
                }
                else if (selectLines(mp, 2, &m_bias3, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"3";
                }
            }
            else if (m_showIndicator == L"ROC")
            {
                if (selectLines(mp, 2, &m_roc, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"ROC";
                }
                else if (selectLines(mp, 2, &m_rocMa, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"ROCMA";
                }
            }
            else if (m_showIndicator == L"WR")
            {
                if (selectLines(mp, 2, &m_wr1, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"1";
                }
                else if (selectLines(mp, 2, &m_wr2, index))
                {
                    m_selectShape = L"WR";
                    m_selectShapeEx = L"2";
                }
            }
            else if (m_showIndicator == L"CCI")
            {
                if (selectLines(mp, 2, &m_cci, index))
                {
                    m_selectShape = m_showIndicator;
                }
            }
            else if (m_showIndicator == L"BBI")
            {
                if (selectLines(mp, 2, &m_bbi, index))
                {
                    m_selectShape = m_showIndicator;
                }
            }
            else if (m_showIndicator == L"TRIX")
            {
                if (selectLines(mp, 2, &m_trix, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"TRIX";
                }
                else if (selectLines(mp, 2, &m_trixMa, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"TRIXMA";
                }
            }
            else if (m_showIndicator == L"DMA")
            {
                if (selectLines(mp, 2, &m_dma1, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"DIF";
                }
                else if (selectLines(mp, 2, &m_dma2, index))
                {
                    m_selectShape = m_showIndicator;
                    m_selectShapeEx = L"DIFMA";
                }
            }
        }
        else if (mp.y >= candleHeight && mp.y <= candleHeight + volHeight)
        {
            double volY = getChartY(1, m_data.get(index).m_volume);
            double zeroY = getChartY(1, 0);
            double minValue = volY > zeroY ? zeroY : volY;
            double maxValue = volY > zeroY ? volY : zeroY;
            if (mp.y >= minValue && mp.y <= maxValue)
            {
                m_selectShape = L"VOL";
            }
        }
        else if (mp.y >= 0 && mp.y <= candleHeight)
        {
            bool isTrend = m_cycle == L"trend";
            if (!isTrend)
            {
                if (m_mainIndicator == L"BOLL")
                {
                    if (selectLines(mp, 0, &m_bollMid, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"MID";
                    }
                    else if (selectLines(mp, 0, &m_bollUp, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"UP";
                    }
                    else if (selectLines(mp, 0, &m_bollDown, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"DOWN";
                    }
                }
                else if (m_mainIndicator == L"MA")
                {
                    if (selectLines(mp, 0, &m_ma5, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"5";
                    }
                    else if (selectLines(mp, 0, &m_ma10, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"10";
                    }
                    else if (selectLines(mp, 0, &m_ma20, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"20";
                    }
                    else if (selectLines(mp, 0, &m_ma30, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"30";
                    }
                    else if (selectLines(mp, 0, &m_ma120, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"120";
                    }
                    else if (selectLines(mp, 0, &m_ma250, index))
                    {
                        m_selectShape = m_mainIndicator;
                        m_selectShapeEx = L"250";
                    }
                }
            }
            if (m_selectShape == L"")
            {
                double highY = getChartY(0, m_data.get(index).m_high);
                double lowY = getChartY(0, m_data.get(index).m_low);
                if (isTrend)
                {
                    if (selectLines(mp, 0, &m_closeArr, index))
                    {
                        m_selectShape = L"CANDLE";
                    }
                }
                else
                {
                    double minValue = lowY > highY ? highY : lowY;
                    double maxValue = lowY < highY ? highY : lowY;
                    if (mp.y >= minValue && mp.y <= maxValue)
                    {
                        m_selectShape = L"CANDLE";
                    }
                }
            }
        }
        if (m_shapes.size() > 0)
        {
            for (int i = 0; i < m_shapes.size(); i++)
            {
                BaseShape *shape = m_shapes.get(i);
                if (shape->m_leftOrRight)
                {
                    if (selectLines(mp, shape->m_divIndex, &shape->m_datas, index))
                    {
                        m_selectShape = shape->m_shapeName;
                        break;
                    }
                }
                else
                {
                    if (selectLinesInRight(mp, shape->m_divIndex, &shape->m_datas, index))
                    {
                        m_selectShape = shape->m_shapeName;
                        break;
                    }
                }
            }
        }
    }

    void FCChart::keyDownChart(char key){
        if (key == 38)
        {
            zoomOutChart();
        }
        else if (key == 40)
        {
            zoomInChart();
        }
        else if (key == 37)
        {
            scrollLeftChart(1);
        }
        else if (key == 39)
        {
            scrollRightChart(1);
        }
    }

    void FCChart::lineXY(double x1, double y1, double x2, double y2, double oX, double oY) {
        m_kChart = 0;
        m_bChart = 0;
        if ((x1 - oX) != (x2 - oX))
        {
            m_kChart = ((y2 - oY) - (y1 - oY)) / ((x2 - oX) - (x1 - oX));
            m_bChart = (y1 - oY) - m_kChart * (x1 - oX);
        }
    }

    double FCChart::linearRegressionEquation(ArrayList<double>* list) {
        double result = 0;
        double sumX = 0;
        double sumY = 0;
        double sumUp = 0;
        double sumDown = 0;
        double xAvg = 0;
        double yAvg = 0;
        m_kChart = 0;
        m_bChart = 0;
        int length = list->size();
        if (length > 1)
        {
            for (int i = 0; i < length; i++)
            {
                sumX += i + 1;
                sumY += list->get(i);
            }
            xAvg = sumX / length;
            yAvg = sumY / length;
            for (int i = 0; i < length; i++)
            {
                sumUp += (i + 1 - xAvg) * (list->get(i) - yAvg);
                sumDown += (i + 1 - xAvg) * (i + 1 - xAvg);
            }
            m_kChart = sumUp / sumDown;
            m_bChart = yAvg - m_kChart * xAvg;
        }
        return result;
    }

    ArrayList<double> FCChart::llvValue(ArrayList<double>* ticks, int days) {
        ArrayList<double> llv;
        double min = ticks->get(0);
        for (int i = 0; i < ticks->size(); i++)
        {
            if (i >= days)
            {
                min = ticks->get(i);
                for (int j = i; j > i - days; j--)
                {
                    if (min > ticks->get(j))
                    {
                        min = ticks->get(j);
                    }
                }
                llv.add(min);
            }
            else
            {
                if (min > ticks->get(i))
                {
                    min = ticks->get(i);
                }
                llv.add(min);
            }
        }
        return llv;
    }

    double FCChart::maxValue(ArrayList<double>* list) {
        int length = list->size();
        double max = 0;
        for (int i = 0; i < length; i++)
        {
            if (i == 0)
            {
                max = list->get(i);
            }
            else
            {
                if (max < list->get(i))
                {
                    max = list->get(i);
                }
            }
        }
        return max;
    }

    double FCChart::minValue(ArrayList<double>* list) {
        int length = list->size();
        double min = 0;
        for (int i = 0; i < length; i++)
        {
            if (i == 0)
            {
                min = list->get(i);
            }
            else
            {
                if (min > list->get(i))
                {
                    min = list->get(i);
                }
            }
        }
        return min;
    }

    ArrayList<double> FCChart::maValue(ArrayList<double>* ticks, int days) {
        double maSum = 0;
        ArrayList<double> mas;
        double last = 0;
        for (int i = 0; i < ticks->size(); i++)
        {
            double ma = 0;
            if (i >= days)
            {
                last = ticks->get(i - days);
                maSum = maSum + ticks->get(i) - last;
                ma = maSum / days;
            }
            else
            {
                maSum += ticks->get(i);
                ma = maSum / (i + 1);
            }
            mas.add(ma);
        }
        return mas;
    }

    void FCChart::onPaint(FCPaint* paint, const FCRect& clipRect) {
        FCView::onPaint(paint, clipRect);
        drawChartScale(paint, clipRect);
        drawChartStock(paint, clipRect);
        drawChartPlot(paint, clipRect);
        drawChartCrossLine(paint, clipRect);
    }

    void FCChart::onTouchDown(FCTouchInfo touchInfo) {
        FCView::onTouchDown(touchInfo);
        touchDownChart(touchInfo.m_firstTouch, touchInfo.m_firstPoint, touchInfo.m_secondTouch, touchInfo.m_secondPoint, touchInfo.m_clicks);
        invalidate();
    }

    void FCChart::onTouchMove(FCTouchInfo touchInfo) {
        FCView::onTouchMove(touchInfo);
        touchMoveChart(touchInfo.m_firstTouch, touchInfo.m_firstPoint, touchInfo.m_secondTouch, touchInfo.m_secondPoint);
        invalidate();
    }

    void FCChart::onTouchUp(FCTouchInfo touchInfo) {
        FCView::onTouchUp(touchInfo);
        m_firstTouchIndexCacheChart = -1;
        m_secondTouchIndexCacheChart = -1;
        invalidate();
    }

    void FCChart::onTouchWheel(FCTouchInfo touchInfo) {
        FCView::onTouchWheel(touchInfo);
        if (touchInfo.m_delta > 0)
        {
            zoomOutChart();
        }
        else if (touchInfo.m_delta < 0)
        {
            zoomInChart();
        }
        invalidate();
    }

    void FCChart::onKeyDown(char key) {
        FCView::onKeyDown(key);
        if (key == 38)
        {
            zoomOutChart();
        }
        else if (key == 40)
        {
            zoomInChart();
        }
        invalidate();
    }

    void FCChart::parallelogram(double x1, double y1, double x2, double y2, double x3, double y3) {
        m_x4Chart = x1 + x3 - x2;
        m_y4Chart = y1 + y3 - y2;
    }

    void FCChart::rectangleXYWH(double x1, double y1, double x2, double y2) {
        m_xChart = x1 < x2 ? x1 : x2;
        m_yChart = y1 < y2 ? y1 : y2;
        m_wChart = x1 - x2 > 0 ? x1 - x2 : x2 - x1;
        m_hChart = y1 - y2 > 0 ? y1 - y2 : y2 - y1;
        if (m_wChart <= 0)
        {
            m_wChart = 4;
        }
        if (m_hChart <= 0)
        {
            m_hChart = 4;
        }
    }

    void FCChart::resetChartVisibleRecord() {
        int rowsCount = m_data.size();
        double workingAreaWidth = getChartWorkAreaWidth();
        if (m_autoFillHScale)
        {
            if (workingAreaWidth > 0 && rowsCount > 0)
            {
                m_hScalePixel = workingAreaWidth / rowsCount;
                m_firstVisibleIndex = 0;
                m_lastVisibleIndex = rowsCount - 1;
            }
        }
        else
        {
            int maxVisibleRecord =
                getChartMaxVisibleCount(m_hScalePixel, workingAreaWidth);
            //没数据时重置
            if (rowsCount == 0)
            {
                m_firstVisibleIndex = -1;
                m_lastVisibleIndex = -1;
            }
            else
            {
                //数据不足一屏时
                if (rowsCount < maxVisibleRecord)
                {
                    m_lastVisibleIndex = rowsCount - 1;
                    m_firstVisibleIndex = 0;
                }
                //数据超过一屏时
                else
                {
                    //显示中间的数据时
                    if (m_firstVisibleIndex != -1 &&
                        m_lastVisibleIndex != -1 &&
                        !m_lastRecordIsVisible)
                    {
                        int index = getChartIndexByDate(m_lastVisibleKey);
                        if (index != -1)
                        {
                            m_lastVisibleIndex = index;
                        }
                        m_firstVisibleIndex =
                            m_lastVisibleIndex - maxVisibleRecord + 1;
                        if (m_firstVisibleIndex < 0)
                        {
                            m_firstVisibleIndex = 0;
                            m_lastVisibleIndex = m_firstVisibleIndex + maxVisibleRecord;
                            checkChartLastVisibleIndex();
                        }
                    }
                    else
                    {
                        //第一条或最后一条数据被显示时
                        m_lastVisibleIndex = rowsCount - 1;
                        m_firstVisibleIndex =
                            m_lastVisibleIndex - maxVisibleRecord + 1;
                        if (m_firstVisibleIndex > m_lastVisibleIndex)
                        {
                            m_firstVisibleIndex = m_lastVisibleIndex;
                        }
                    }
                }
            }
        }
    }

    ArrayList<double> FCChart::refValue(ArrayList<double>* ticks, int days) {
        ArrayList<double> refArr;
        int length = ticks->size();
        for (int i = 0; i < length; i++)
        {
            double refV = 0;
            if (i >= days)
            {
                refV = ticks->get(i - days);
            }
            else
            {
                refV = ticks->get(0);
            }
            refArr.add(refV);
        }
        return refArr;
    }

    void FCChart::scrollLeftChart(int step){
        m_offsetX = 0;
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        if(m_showCrossLine){
            m_crossStopIndex = m_crossStopIndex - step;
            if(m_crossStopIndex >= m_firstVisibleIndex){
                step = 0;
            }
            else if(m_crossStopIndex < 0){
                m_crossStopIndex = 0;
            }
        }
        if(step > 0){
            int subIndex = m_lastVisibleIndex - m_firstVisibleIndex;
            int fIndex = m_firstVisibleIndex - step;
            if(fIndex < 0){
                fIndex = 0;
            }
            int eIndex = fIndex + subIndex;
            m_firstVisibleIndex = fIndex;
            m_lastVisibleIndex = eIndex;
        }
        checkChartLastVisibleIndex();
        calculateChartMaxMin();
    }

    void FCChart::scrollRightChart(int step){
        m_offsetX = 0;
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        int dataCount = m_data.size();
        if(m_showCrossLine){
            m_crossStopIndex = m_crossStopIndex + step;
            if(m_crossStopIndex <= m_lastVisibleIndex){
                step = 0;
            }
            else if(m_crossStopIndex > dataCount - 1){
                m_crossStopIndex = dataCount - 1;
            }
        }
        if(step > 0){
            int subIndex = m_lastVisibleIndex - m_firstVisibleIndex;
            int eIndex = m_lastVisibleIndex + step;
            if(eIndex > dataCount - 1){
                eIndex = dataCount - 1;
            }
            int fIndex = eIndex - subIndex;
            m_firstVisibleIndex = fIndex;
            m_lastVisibleIndex = eIndex;
        }
        checkChartLastVisibleIndex();
        calculateChartMaxMin();
    }

    bool FCChart::selectLine(const FCPoint& mp, double x1, double y1, double x2, double y2) {
        lineXY(x1, y1, x2, y2, 0, 0);
        if (!(m_kChart == 0 && m_bChart == 0))
        {
            if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                mp.y / (mp.x * m_kChart + m_bChart) <= 1.1)
            {
                return true;
            }
        }
        else
        {
            if (mp.x >= x1 - m_plotPointSizeChart &&
                mp.x <= x1 + m_plotPointSizeChart)
            {
                return true;
            }
        }
        return false;
    }

    bool FCChart::selectRay(const FCPoint& mp, double x1, double y1, double x2, double y2) {
        lineXY(x1, y1, x2, y2, 0, 0);
        if (!(m_kChart == 0 && m_bChart == 0))
        {
            if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                mp.y / (mp.x * m_kChart + m_bChart) <= 1.1)
            {
                if (x1 >= x2)
                {
                    if (mp.x > x1 + m_plotPointSizeChart)
                    {
                        return false;
                    }
                }
                else if (x1 < x2)
                {
                    if (mp.x < x1 - m_plotPointSizeChart)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        else
        {
            if (mp.x >= x1 - m_plotPointSizeChart &&
                mp.x <= x1 + m_plotPointSizeChart)
            {
                if (y1 >= y2)
                {
                    if (mp.y <= y1 - m_plotPointSizeChart)
                    {
                        return true;
                    }
                }
                else
                {
                    if (mp.y >= y1 - m_plotPointSizeChart)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    bool FCChart::selectSegment(const FCPoint& mp, double x1, double y1, double x2, double y2) {
        lineXY(x1, y1, x2, y2, 0, 0);
        double smallX = x1 <= x2 ? x1 : x2;
        double smallY = y1 <= y2 ? y1 : y2;
        double bigX = x1 > x2 ? x1 : x2;
        double bigY = y1 > y2 ? y1 : y2;
        if (mp.x >= smallX - 2 &&
            mp.x <= bigX + 2 &&
            mp.y >= smallY - 2 &&
            mp.y <= bigY + 2)
        {
            if (m_kChart != 0 || m_bChart != 0)
            {
                if (mp.y / (mp.x * m_kChart + m_bChart) >= 0.9 &&
                    mp.y / (mp.x * m_kChart + m_bChart) <= 1.1)
                {
                    return true;
                }
            }
            else
            {
                if (mp.x >= x1 - m_plotPointSizeChart &&
                    mp.x <= x1 + m_plotPointSizeChart)
                {
                    return true;
                }
            }
        }
        return false;
    }

    double FCChart::standardDeviationSum(ArrayList<double>* listValue, double avgValue) {
        double targetValue = listValue->get(listValue->size() - 1);
        double sumValue = (targetValue - avgValue) * (targetValue - avgValue);
        for (int i = 0; i < listValue->size() - 1; i++)
        {
            double ileft = listValue->get(i);
            sumValue = sumValue + (ileft - avgValue) * (ileft - avgValue);
        }
        return sumValue;
    }

    FCPlot* FCChart::selectPlot(const FCPoint& mp) {
        FCPlot *sPlot = 0;
        m_startMovePlot = false;
        m_selectPlotPoint = -1;
        for (int i = 0; i < m_plots.size(); i++)
        {
            FCPlot *plot = m_plots.get(i);
            int index1 = 0, index2 = 0, index3 = 0;
            double mpx1 = 0, mpy1 = 0, mpx2 = 0, mpy2 = 0, mpx3 = 0, mpy3 = 0;
            //检查关键点
            if (plot->m_key1 > 0)
            {
                index1 = getChartIndexByDate(plot->m_key1);
                mpx1 = getChartX(index1);
                mpy1 = getChartY(0, plot->m_value1);
                if (mp.x >= mpx1 - m_plotPointSizeChart &&
                    mp.x <= mpx1 + m_plotPointSizeChart &&
                    mp.y >= mpy1 - m_plotPointSizeChart &&
                    mp.y <= mpy1 + m_plotPointSizeChart)
                {
                    sPlot = plot;
                    m_selectPlotPoint = 0;
                    break;
                }
            }
            if (plot->m_key2 > 0)
            {
                index2 = getChartIndexByDate(plot->m_key2);
                mpx2 = getChartX(index2);
                mpy2 = getChartY(0, plot->m_value2);
                if (mp.x >= mpx2 - m_plotPointSizeChart &&
                    mp.x <= mpx2 + m_plotPointSizeChart &&
                    mp.y >= mpy2 - m_plotPointSizeChart &&
                    mp.y <= mpy2 + m_plotPointSizeChart)
                {
                    sPlot = plot;
                    m_selectPlotPoint = 1;
                    break;
                }
            }
            if (plot->m_key3 > 0)
            {
                index3 = getChartIndexByDate(plot->m_key3);
                mpx3 = getChartX(index3);
                mpy3 = getChartY(0, plot->m_value3);
                if (mp.x >= mpx3 - m_plotPointSizeChart &&
                    mp.x <= mpx3 + m_plotPointSizeChart &&
                    mp.y >= mpy3 - m_plotPointSizeChart &&
                    mp.y <= mpy3 + m_plotPointSizeChart)
                {
                    sPlot = plot;
                    m_selectPlotPoint = 2;
                    break;
                }
            }
            //判断其余部分的选中
            if (m_selectPlotPoint == -1)
            {
                if (plot->m_plotType == L"Line")
                {
                    m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot->m_plotType == L"ArrowSegment")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot->m_plotType == L"AngleLine")
                {
                    m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx3, mpy3);
                    }
                }
                else if (plot->m_plotType == L"Parallel")
                {
                    m_startMovePlot = selectLine(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                        double newB = mpy3 - m_kChart * mpx3;
                        if (mpx2 == mpx1)
                        {
                            if (mp.x >= mpx3 - m_plotPointSizeChart &&
                                mp.x <= mpx3 + m_plotPointSizeChart)
                            {
                                m_startMovePlot = true;
                            }
                        }
                        else
                        {
                            double newX1 = m_leftVScaleWidth;
                            double newY1 = newX1 * m_kChart + newB;
                            double newX2 = getSize().cx - m_rightVScaleWidth;
                            double newY2 = newX2 * m_kChart + newB;
                            m_startMovePlot =
                                selectLine(mp, newX1, newY1, newX2, newY2);
                        }
                    }
                }
                else if (plot->m_plotType == L"LRLine")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot->m_plotType == L"Segment")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot->m_plotType == L"Ray")
                {
                    m_startMovePlot = selectRay(mp, mpx1, mpy1, mpx2, mpy2);
                }
                else if (plot->m_plotType == L"Triangle")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot =
                            selectSegment(mp, mpx2, mpy2, mpx3, mpy3);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot =
                            selectSegment(mp, mpx1, mpy1, mpx3, mpy3);
                    }
                }
                else if (plot->m_plotType == L"SymmetricTriangle")
                {
                    if (mpx2 != mpx1)
                    {
                        double a = (double)(mpy2 - mpy1) / (double)(mpx2 - mpx1);
                        double b = mpy1 - a * mpx1;
                        double c = -a;
                        double d = mpy3 - c * mpx3;
                        double leftX = m_leftVScaleWidth;
                        double leftY = leftX * a + b;
                        double rightX = getSize().cx - m_rightVScaleWidth;
                        double rightY = rightX * a + b;
                        m_startMovePlot = selectSegment(mp, leftX, leftY, rightX, rightY);
                        if (!m_startMovePlot)
                        {
                            leftY = leftX * c + d;
                            rightY = rightX * c + d;
                            m_startMovePlot = selectSegment(mp, leftX, leftY, rightX, rightY);
                        }
                    }
                    else
                    {
                        double divHeight = getCandleDivHeight();
                        m_startMovePlot = selectSegment(mp, mpx1, 0, mpx1, divHeight);
                        if (!m_startMovePlot)
                        {
                            m_startMovePlot = selectSegment(mp, mpx3, 0, mpx3, divHeight);
                        }
                    }
                }
                else if (plot->m_plotType == L"Rect")
                {
                    double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                    double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                    double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                    double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX2, sY1, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY1, sX1, sY2);
                    }
                }
                else if (plot->m_plotType == L"BoxLine")
                {
                    double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                    double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                    double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                    double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX2, sY1, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY1, sX1, sY2);
                    }
                }
                else if (plot->m_plotType == L"TironeLevels")
                {
                    double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                    double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                    double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                    double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                }
                else if (plot->m_plotType == L"QuadrantLines")
                {
                    double sX1 = mpx1 > mpx2 ? mpx2 : mpx1;
                    double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                    double sX2 = mpx1 > mpx2 ? mpx1 : mpx2;
                    double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                    m_startMovePlot = selectSegment(mp, sX1, sY1, sX2, sY1);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot = selectSegment(mp, sX1, sY2, sX2, sY2);
                    }
                }
                else if (plot->m_plotType == L"GoldenRatio")
                {
                    double sY1 = mpy1 > mpy2 ? mpy2 : mpy1;
                    double sY2 = mpy1 > mpy2 ? mpy1 : mpy2;
                    ArrayList<double> ranges;
                    ranges.add(0);
                    ranges.add(0.236);
                    ranges.add(0.382);
                    ranges.add(0.5);
                    ranges.add(0.618);
                    ranges.add(0.809);
                    ranges.add(1);
                    ranges.add(1.382);
                    ranges.add(1.618);
                    ranges.add(2);
                    ranges.add(2.382);
                    ranges.add(2.618);
                    for (int j = 0; j < ranges.size(); j++)
                    {
                        double newY = sY1 <= sY2
                            ? sY1 + (sY2 - sY1) * ranges.get(j)
                            : sY2 + (sY1 - sY2) * (1 - ranges.get(j));
                        m_startMovePlot = selectSegment(mp, m_leftVScaleWidth,
                            newY, getSize().cx - m_rightVScaleWidth, newY);
                        if (m_startMovePlot)
                        {
                            break;
                        }
                    }
                }
                else if (plot->m_plotType == L"Cycle")
                {
                    double r = sqrt(((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)));
                    double round =
                        (mp.x - mpx1) * (mp.x - mpx1) + (mp.y - mpy1) * (mp.y - mpy1);
                    if (round / (r * r) >= 0.9 && round / (r * r) <= 1.1)
                    {
                        m_startMovePlot = true;
                    }
                }
                else if (plot->m_plotType == L"CircumCycle")
                {
                    ellipseOR(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                    double round = (mp.x - m_oXChart) * (mp.x - m_oXChart) +
                        (mp.y - m_oYChart) * (mp.y - m_oYChart);
                    if (round / (m_rChart * m_rChart) >= 0.9 &&
                        round / (m_rChart * m_rChart) <= 1.1)
                    {
                        m_startMovePlot = true;
                    }
                }
                else if (plot->m_plotType == L"Ellipse")
                {
                    double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                    if (mpx1 <= mpx2)
                    {
                        x1 = mpx2;
                        y1 = mpy2;
                        x2 = mpx1;
                        y2 = mpy1;
                    }
                    else
                    {
                        x1 = mpx1;
                        y1 = mpy1;
                        x2 = mpx2;
                        y2 = mpy2;
                    }
                    double x = x1 - (x1 - x2);
                    double y = 0;
                    double width = (x1 - x2) * 2;
                    double height = 0;
                    if (y1 >= y2)
                    {
                        height = (y1 - y2) * 2;
                    }
                    else
                    {
                        height = (y2 - y1) * 2;
                    }
                    y = y2 - height / 2;
                    double a = width / 2;
                    double b = height / 2;
                    m_startMovePlot = ellipseHasPoint(
                        mp.x, mp.y, x + (width / 2), y + (height / 2), a, b);
                }
                else if (plot->m_plotType == L"LRBand")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        ArrayList<double> list;
                        int minIndex = index1 > index2 ? index2 : index1;
                        int maxIndex = index1 > index2 ? index1 : index2;
                        for (int j = minIndex; j <= maxIndex; j++)
                        {
                            list.add(m_data.get(j).m_close);
                        }
                        linearRegressionEquation(&list);
                        getLRBandRange(plot, m_kChart, m_bChart);
                        mpy1 = getChartY(0, plot->m_value1 + m_upSubValue);
                        mpy2 = getChartY(0, plot->m_value2 + m_upSubValue);
                        m_startMovePlot =
                            selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                        if (!m_startMovePlot)
                        {
                            mpy1 = getChartY(0, plot->m_value1 - m_downSubValue);
                            mpy2 = getChartY(0, plot->m_value2 - m_downSubValue);
                            m_startMovePlot =
                                selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                        }
                    }
                }
                else if (plot->m_plotType == L"LRChannel")
                {
                    lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                    double rightX = getSize().cx - m_rightVScaleWidth;
                    double rightY = rightX * m_kChart + m_bChart;
                    m_startMovePlot =
                        selectSegment(mp, mpx1, mpy1, rightX, rightY);
                    if (!m_startMovePlot)
                    {
                        ArrayList<double> list;
                        int minIndex = index1 > index2 ? index2 : index1;
                        int maxIndex = index1 > index2 ? index1 : index2;
                        for (int j = minIndex; j <= maxIndex; j++)
                        {
                            list.add(m_data.get(j).m_close);
                        }
                        linearRegressionEquation(&list);
                        getLRBandRange(plot, m_kChart, m_bChart);
                        mpy1 = getChartY(0, plot->m_value1 + m_upSubValue);
                        mpy2 = getChartY(0, plot->m_value2 + m_upSubValue);
                        lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                        rightY = rightX * m_kChart + m_bChart;
                        m_startMovePlot =
                            selectSegment(mp, mpx1, mpy1, rightX, rightY);
                        if (!m_startMovePlot)
                        {
                            mpy1 = getChartY(0, plot->m_value1 - m_downSubValue);
                            mpy2 = getChartY(0, plot->m_value2 - m_downSubValue);
                            lineXY(mpx1, mpy1, mpx2, mpy2, 0, 0);
                            rightY = rightX * m_kChart + m_bChart;
                            m_startMovePlot =
                                selectSegment(mp, mpx1, mpy1, rightX, rightY);
                        }
                    }
                }
                else if (plot->m_plotType == L"ParalleGram")
                {
                    parallelogram(mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        m_startMovePlot =
                            selectSegment(mp, mpx2, mpy2, mpx3, mpy3);
                        if (!m_startMovePlot)
                        {
                            m_startMovePlot = selectSegment(mp, mpx3, mpy3, m_x4Chart, m_y4Chart);
                            if (!m_startMovePlot)
                            {
                                m_startMovePlot = selectSegment(mp, m_x4Chart, m_y4Chart, mpx1, mpy1);
                            }
                        }
                    }
                }
                else if (plot->m_plotType == L"SpeedResist")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        if (mpx1 != mpx2 && mpy1 != mpy2)
                        {
                            FCPoint firstP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) / 3) };
                            FCPoint secondP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 2 / 3) };
                            FCPoint startP = { (int)mpx1, (int)mpy1 };
                            double fK = 0, fB = 0, sK = 0, sB = 0;
                            lineXY(startP.x, startP.y, firstP.x, firstP.y, 0, 0);
                            fK = m_kChart;
                            fB = m_bChart;
                            lineXY(startP.x, startP.y, secondP.x, secondP.y, 0, 0);
                            sK = m_kChart;
                            sB = m_bChart;
                            double newYF = 0, newYS = 0;
                            double newX = 0;
                            if (mpx2 > mpx1)
                            {
                                newYF = fK * (getSize().cx - m_rightVScaleWidth) + fB;
                                newYS = sK * (getSize().cx - m_rightVScaleWidth) + sB;
                                newX = (getSize().cx - m_rightVScaleWidth);
                            }
                            else
                            {
                                newYF = fB;
                                newYS = sB;
                                newX = m_leftVScaleWidth;
                            }
                            m_startMovePlot =
                                selectSegment(mp, startP.x, startP.y, newX, newYF);
                            if (!m_startMovePlot)
                            {
                                m_startMovePlot =
                                    selectSegment(mp, startP.x, startP.y, newX, newYS);
                            }
                        }
                    }
                }
                else if (plot->m_plotType == L"FiboFanline")
                {
                    m_startMovePlot = selectSegment(mp, mpx1, mpy1, mpx2, mpy2);
                    if (!m_startMovePlot)
                    {
                        if (mpx1 != mpx2 && mpy1 != mpy2)
                        {
                            FCPoint firstP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.382) };
                            FCPoint secondP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.5) };
                            FCPoint thirdP = { (int)mpx2, (int)(mpy2 - (mpy2 - mpy1) * 0.618) };
                            FCPoint startP = { (int)mpx1, (int)mpy1 };
                            ArrayList<FCPoint> listP;
                            listP.add(firstP);
                            listP.add(secondP);
                            listP.add(thirdP);
                            int listSize = listP.size();
                            for (int j = 0; j < listSize; j++)
                            {
                                lineXY(startP.x, startP.y, listP.get(j).x, listP.get(j).y, 0, 0);
                                double newX = 0;
                                double newY = 0;
                                if (mpx2 > mpx1)
                                {
                                    newY = m_kChart * (getSize().cx - m_rightVScaleWidth) +
                                        m_bChart;
                                    newX = (getSize().cx - m_rightVScaleWidth);
                                }
                                else
                                {
                                    newY = m_bChart;
                                    newX = m_leftVScaleWidth;
                                }
                                m_startMovePlot =
                                    selectSegment(mp, startP.x, startP.y, newX, newY);
                                if (m_startMovePlot)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                else if (plot->m_plotType == L"FiboTimezone")
                {
                    int fValue = 1;
                    int aIndex = index1;
                    int pos = 1;
                    double divHeight = getCandleDivHeight();
                    m_startMovePlot =
                        selectSegment(mp, mpx1, 0, mpx1, divHeight);
                    if (!m_startMovePlot)
                    {
                        while (aIndex + fValue <= m_lastVisibleIndex)
                        {
                            fValue = fibonacciValue(pos);
                            int newIndex = aIndex + fValue;
                            double newX = getChartX(newIndex);
                            m_startMovePlot =
                                selectSegment(mp, newX, 0, newX, divHeight);
                            if (m_startMovePlot)
                            {
                                break;
                            }
                            pos++;
                        }
                    }
                }
                else if (plot->m_plotType == L"Percent")
                {
                    ArrayList<int> list = getPercentParams(mpy1, mpy2);
                    for (int j = 0; j < list.size(); j++)
                    {
                        m_startMovePlot = selectSegment(mp, m_leftVScaleWidth,
                            list.get(j), getSize().cx - m_rightVScaleWidth, list.get(j));
                        if (m_startMovePlot)
                        {
                            break;
                        }
                    }
                }
                if (m_startMovePlot)
                {
                    sPlot = plot;
                    plot->m_startKey1 = plot->m_key1;
                    plot->m_startValue1 = plot->m_value1;
                    plot->m_startKey2 = plot->m_key2;
                    plot->m_startValue2 = plot->m_value2;
                    plot->m_startKey3 = plot->m_key3;
                    plot->m_startValue3 = plot->m_value3;
                    break;
                }
            }
        }
        return sPlot;
    }

    void FCChart::setChartVisibleIndex(int firstVisibleIndex, int lastVisibleIndex) {
        double xScalePixel =
            getChartWorkAreaWidth() / (lastVisibleIndex - firstVisibleIndex + 1);
        if (xScalePixel < 1000000)
        {
            m_firstVisibleIndex = firstVisibleIndex;
            m_lastVisibleIndex = lastVisibleIndex;
            //设置最后一条记录是否可见
            if (lastVisibleIndex != m_data.size() - 1)
            {
                m_lastRecordIsVisible = false;
            }
            else
            {
                m_lastRecordIsVisible = true;
            }
            m_hScalePixel = xScalePixel;
            checkChartLastVisibleIndex();
        }
    }

    bool FCChart::selectLines(const FCPoint& mp, int divIndex, ArrayList<double>* datas, int curIndex) {
        if (datas->size() > 0)
        {
            double topY = getChartY(divIndex, datas->get(curIndex));
            if (m_hScalePixel <= 1)
            {
                if (mp.y >= topY - 8 && mp.y <= topY + 8)
                {
                    return true;
                }
            }
            else
            {
                int index = curIndex;
                double scaleX = getChartX(index);
                double judgeTop = 0;
                double judgeScaleX = scaleX;
                if (mp.x >= scaleX)
                {
                    int leftIndex = curIndex + 1;
                    if (curIndex < m_lastVisibleIndex)
                    {
                        double rightValue = datas->get(leftIndex);
                        judgeTop = getChartY(divIndex, rightValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                else
                {
                    judgeScaleX = scaleX - m_hScalePixel;
                    int rightIndex = curIndex - 1;
                    if (curIndex > 0)
                    {
                        double leftValue = datas->get(rightIndex);
                        judgeTop = getChartY(divIndex, leftValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                double lineWidth = 4;
                double judgeX = 0, judgeY = 0, judgeW = 0, judgeH = 0;
                if (judgeTop >= topY)
                {
                    judgeX = judgeScaleX;
                    judgeY = topY - 2 - lineWidth;
                    judgeW = m_hScalePixel;
                    judgeH = judgeTop - topY + lineWidth < 4
                        ? 4
                        : judgeTop - topY + 4 + lineWidth;
                }
                else
                {
                    judgeX = judgeScaleX;
                    judgeY = judgeTop - 2 - lineWidth / 2;
                    judgeW = m_hScalePixel;
                    judgeH = topY - judgeTop + lineWidth < 4
                        ? 4
                        : topY - judgeTop + 4 + lineWidth;
                }

                if (mp.x >= judgeX &&
                    mp.x <= judgeX + judgeW &&
                    mp.y >= judgeY &&
                    mp.y <= judgeY + judgeH)
                {
                    return true;
                }
            }
        }
        return false;
    }

    bool FCChart::selectLinesInRight(const FCPoint& mp, int divIndex, ArrayList<double>* datas, int curIndex) {
        if (datas->size() > 0)
        {
            double topY = getChartYInRight(divIndex, datas->get(curIndex));
            if (m_hScalePixel <= 1)
            {
                if (mp.y >= topY - 8 && mp.y <= topY + 8)
                {
                    return true;
                }
            }
            else
            {
                int index = curIndex;
                double scaleX = getChartX(index);
                double judgeTop = 0;
                double judgeScaleX = scaleX;
                if (mp.x >= scaleX)
                {
                    int leftIndex = curIndex + 1;
                    if (curIndex < m_lastVisibleIndex)
                    {
                        double rightValue = datas->get(leftIndex);
                        judgeTop = getChartYInRight(divIndex, rightValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                else
                {
                    judgeScaleX = scaleX - m_hScalePixel;
                    int rightIndex = curIndex - 1;
                    if (curIndex > 0)
                    {
                        double leftValue = datas->get(rightIndex);
                        judgeTop = getChartYInRight(divIndex, leftValue);
                    }
                    else
                    {
                        judgeTop = topY;
                    }
                }
                double lineWidth = 4;
                double judgeX = 0, judgeY = 0, judgeW = 0, judgeH = 0;
                if (judgeTop >= topY)
                {
                    judgeX = judgeScaleX;
                    judgeY = topY - 2 - lineWidth;
                    judgeW = m_hScalePixel;
                    judgeH = judgeTop - topY + lineWidth < 4
                        ? 4
                        : judgeTop - topY + 4 + lineWidth;
                }
                else
                {
                    judgeX = judgeScaleX;
                    judgeY = judgeTop - 2 - lineWidth / 2;
                    judgeW = m_hScalePixel;
                    judgeH = topY - judgeTop + lineWidth < 4
                        ? 4
                        : topY - judgeTop + 4 + lineWidth;
                }

                if (mp.x >= judgeX &&
                    mp.x <= judgeX + judgeW &&
                    mp.y >= judgeY &&
                    mp.y <= judgeY + judgeH)
                {
                    return true;
                }
            }
        }
        return false;
    }

    void FCChart::touchDownChart(bool firstTouch, const FCPoint& firstPoint, bool secondTouch, const FCPoint& secondPoint, int clicks) {
        m_touchDownPointChart = firstPoint;
        m_crossStopIndex = getChartIndex(firstPoint);
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        m_selectShape = L"";
        m_selectShapeEx = L"";
        m_sPlot = 0;
        if (m_data.size() > 0){
            FCPlot *selectedPlot = selectPlot(firstPoint);
            if (selectedPlot)
            {
                m_sPlot = selectedPlot;
            }
            if (!m_sPlot)
            {
                judgeSelectShape(firstPoint);
            }
        }
        if (clicks == 2)
        {
            m_showCrossLine = !m_showCrossLine;
        }
    }

    void FCChart::touchMoveChart(bool firstTouch, const FCPoint& firstPoint, bool secondTouch, const FCPoint& secondPoint) {
        if (m_data.size() == 0)
        {
            return;
        }
        FCPoint mp = firstPoint;
        m_offsetX = 0;
        m_targetOldX = 0;
        m_targetOldX2 = 0;
        m_crossStopIndex = getChartIndex(mp);
        m_touchPosition = mp;
        FCPlot *sPlot = m_sPlot;
        if (firstTouch && sPlot)
        {
            int newIndex = getChartIndex(mp);
            if (newIndex >= 0 && newIndex < m_data.size())
            {
                double newDate = getChartDateByIndex(newIndex);
                double newValue = getCandleDivValue(mp);
                if (m_selectPlotPoint == 0)
                {
                    sPlot->m_key1 = newDate;
                    sPlot->m_value1 = newValue;
                }
                else if (m_selectPlotPoint == 1)
                {
                    sPlot->m_key2 = newDate;
                    sPlot->m_value2 = newValue;
                }
                else if (m_selectPlotPoint == 2)
                {
                    sPlot->m_key3 = newDate;
                    sPlot->m_value3 = newValue;
                }
                else if (m_startMovePlot)
                {
                    double bValue = getCandleDivValue(m_touchDownPointChart);
                    int bIndex = getChartIndex(m_touchDownPointChart);
                    if (sPlot->m_key1 > 0)
                    {
                        sPlot->m_value1 = sPlot->m_startValue1 + (newValue - bValue);
                        int startIndex1 = getChartIndexByDate(sPlot->m_startKey1);
                        int newIndex1 = startIndex1 + (newIndex - bIndex);
                        if (newIndex1 < 0)
                        {
                            newIndex1 = 0;
                        }
                        else if (newIndex1 > m_data.size() - 1)
                        {
                            newIndex1 = m_data.size() - 1;
                        }
                        sPlot->m_key1 = getChartDateByIndex(newIndex1);
                    }
                    if (sPlot->m_key2 > 0)
                    {
                        sPlot->m_value2 = sPlot->m_startValue2 + (newValue - bValue);
                        int startIndex2 = getChartIndexByDate(sPlot->m_startKey2);
                        int newIndex2 = startIndex2 + (newIndex - bIndex);
                        if (newIndex2 < 0)
                        {
                            newIndex2 = 0;
                        }
                        else if (newIndex2 > m_data.size() - 1)
                        {
                            newIndex2 = m_data.size() - 1;
                        }
                        sPlot->m_key2 = getChartDateByIndex(newIndex2);
                    }
                    if (sPlot->m_key3 > 0)
                    {
                        sPlot->m_value3 = sPlot->m_startValue3 + (newValue - bValue);
                        int startIndex3 = getChartIndexByDate(sPlot->m_startKey3);
                        int newIndex3 = startIndex3 + (newIndex - bIndex);
                        if (newIndex3 < 0)
                        {
                            newIndex3 = 0;
                        }
                        else if (newIndex3 > m_data.size() - 1)
                        {
                            newIndex3 = m_data.size() - 1;
                        }
                        sPlot->m_key3 = getChartDateByIndex(newIndex3);
                    }
                }
            }
            return;
        }
        if (firstTouch && secondTouch)
        {
            if (firstPoint.x > secondPoint.x)
            {
                m_firstTouchPointCacheChart = secondPoint;
                m_secondTouchPointCacheChart = firstPoint;
            }
            else
            {
                m_firstTouchPointCacheChart = firstPoint;
                m_secondTouchPointCacheChart = secondPoint;
            }
            if (m_firstTouchIndexCacheChart == -1 ||
                m_secondTouchIndexCacheChart == -1)
            {
                m_firstTouchIndexCacheChart =
                    getChartIndex(m_firstTouchPointCacheChart);
                m_secondTouchIndexCacheChart =
                    getChartIndex(m_secondTouchPointCacheChart);
                m_firstIndexCacheChart = m_firstVisibleIndex;
                m_lastIndexCacheChart = m_lastVisibleIndex;
            }
        }
        else if (firstTouch)
        {
            m_secondTouchIndexCacheChart = -1;
            if (m_firstTouchIndexCacheChart == -1)
            {
                m_firstTouchPointCacheChart = firstPoint;
                m_firstTouchIndexCacheChart =
                    getChartIndex(m_firstTouchPointCacheChart);
                m_firstIndexCacheChart = m_firstVisibleIndex;
                m_lastIndexCacheChart = m_lastVisibleIndex;
                m_firstPaddingTop = m_candlePaddingTop;
                m_firtstPaddingBottom = m_candlePaddingBottom;
            }
        }

        if (firstTouch && secondTouch)
        {
            if (m_firstTouchIndexCacheChart != -1 &&
                m_secondTouchIndexCacheChart != -1)
            {
                FCPoint fPoint = firstPoint;
                FCPoint sPoint = secondPoint;
                if (firstPoint.x > secondPoint.x)
                {
                    fPoint = secondPoint;
                    sPoint = firstPoint;
                }
                double subX = sPoint.x > fPoint.x ? sPoint.x - fPoint.x : fPoint.x - sPoint.x;
                int subIndex = m_secondTouchIndexCacheChart - m_firstTouchIndexCacheChart > 0 ? m_secondTouchIndexCacheChart - m_firstTouchIndexCacheChart : m_firstTouchIndexCacheChart - m_secondTouchIndexCacheChart;
                if (subX > 0 && subIndex > 0)
                {
                    double newScalePixel = subX / subIndex;
                    if (newScalePixel >= 3)
                    {
                        double intScalePixel = (int)newScalePixel;
                        newScalePixel = intScalePixel;
                    }
                    if (newScalePixel != m_hScalePixel)
                    {
                        int newFirstIndex = m_firstTouchIndexCacheChart;
                        double thisX = fPoint.x;
                        thisX -= newScalePixel;
                        while (thisX > m_leftVScaleWidth + newScalePixel)
                        {
                            newFirstIndex--;
                            if (newFirstIndex < 0)
                            {
                                newFirstIndex = 0;
                                break;
                            }
                            thisX -= newScalePixel;
                        }

                        thisX = sPoint.x;
                        int newSecondIndex = m_secondTouchIndexCacheChart;
                        thisX += newScalePixel;
                        while (
                            thisX < getSize().cx - m_rightVScaleWidth - newScalePixel)
                        {
                            newSecondIndex++;
                            if (newSecondIndex > m_data.size() - 1)
                            {
                                newSecondIndex = m_data.size() - 1;
                                break;
                            }
                            thisX += newScalePixel;
                        }
                        setChartVisibleIndex(newFirstIndex, newSecondIndex);
                        int maxVisibleRecord = getChartMaxVisibleCount(m_hScalePixel, getChartWorkAreaWidth());
                        while (maxVisibleRecord <
                            m_lastVisibleIndex - m_firstVisibleIndex + 1 &&
                            m_lastVisibleIndex > m_firstVisibleIndex)
                        {
                            m_lastVisibleIndex--;
                        }
                        checkChartLastVisibleIndex();
                        resetChartVisibleRecord();
                        calculateChartMaxMin();
                    }
                }
            }
        }
        else if (firstTouch)
        {
            if(!m_autoFillHScale){
                int subIndex =
                (int)((m_firstTouchPointCacheChart.x - firstPoint.x) / m_hScalePixel);
                if (m_allowDragChartDiv)
                {
                    m_candlePaddingTop = m_firstPaddingTop - (m_firstTouchPointCacheChart.y - firstPoint.y);
                    m_candlePaddingBottom = m_firtstPaddingBottom + (m_firstTouchPointCacheChart.y - firstPoint.y);
                }
                int fIndex = m_firstIndexCacheChart + subIndex;
                int lIndex = m_lastIndexCacheChart + subIndex;
                if(fIndex > m_data.size() - 1){
                    fIndex = m_data.size() - 1;
                    lIndex = m_data.size() - 1;
                }
                m_firstVisibleIndex = fIndex;
                m_lastVisibleIndex = lIndex;
                checkChartLastVisibleIndex();
                calculateChartMaxMin();
            }
        }
    }

    void FCChart::update() {
        FCView::update();
        resetChartVisibleRecord();
        checkChartLastVisibleIndex();
        calculateChartMaxMin();
    }

    void FCChart::zoomOutChart() {
        if (!m_autoFillHScale)
        {
            double hScalePixel = m_hScalePixel;
            double oldX = getChartX(m_crossStopIndex);
            if (m_showCrossLine && m_targetOldX == 0)
            {
                m_targetOldX = oldX;
            }
            double pureH = getChartWorkAreaWidth();
            int oriMax = -1, max = -1, deal = 0;
            int dataCount = m_data.size();
            int findex = m_firstVisibleIndex, lindex = m_lastVisibleIndex;
            if (hScalePixel < pureH)
            {
                oriMax = getChartMaxVisibleCount(hScalePixel, pureH);
                if (dataCount < oriMax)
                {
                    deal = 1;
                }
                if (hScalePixel > 3)
                {
                    hScalePixel += 1;
                }
                else
                {
                    if (hScalePixel == 1)
                    {
                        hScalePixel = 2;
                    }
                    else
                    {
                        hScalePixel = hScalePixel * 1.5;
                        if (hScalePixel > 3)
                        {
                            hScalePixel = (int)hScalePixel;
                        }
                    }
                }
                max = getChartMaxVisibleCount(hScalePixel, pureH);
                if (dataCount >= max)
                {
                    if (deal == 1)
                    {
                        lindex = dataCount - 1;
                    }
                    findex = lindex - max + 1;
                    if (findex < 0)
                    {
                        findex = 0;
                    }
                }
            }
            m_hScalePixel = hScalePixel;
            if (m_showCrossLine)
            {
                float sX = m_targetOldX;
                findex = m_crossStopIndex;
                while (sX >= m_leftVScaleWidth + m_hScalePixel / 2)
                {
                    findex = findex - 1;
                    m_offsetX = (float)(sX - m_leftVScaleWidth - m_hScalePixel / 2);
                    sX = (float)(sX - m_hScalePixel);
                }
                findex = findex + 1;
            }
            m_firstVisibleIndex = findex;
            m_lastVisibleIndex = lindex;
            checkChartLastVisibleIndex();
            calculateChartMaxMin();
        }
    }

    void FCChart::zoomInChart() {
        if (!m_autoFillHScale)
        {
            double hScalePixel = m_hScalePixel;
            double oldX = getChartX(m_crossStopIndex);
            if (m_showCrossLine && m_targetOldX2 == 0)
            {
                m_targetOldX2 = oldX;
            }
            double pureH = getChartWorkAreaWidth();
            int max = -1;
            int dataCount = m_data.size();
            int findex = m_firstVisibleIndex, lindex = m_lastVisibleIndex;
            if (hScalePixel > 3)
            {
                hScalePixel -= 1;
            }
            else
            {
                hScalePixel = hScalePixel * 2 / 3;
                if (hScalePixel > 3)
                {
                    hScalePixel = (int)hScalePixel;
                }
            }
            max = getChartMaxVisibleCount(hScalePixel, pureH);
            if (max >= dataCount)
            {
                if (hScalePixel < 1)
                {
                    hScalePixel = pureH / max;
                }
                findex = 0;
                lindex = dataCount - 1;
            }
            else
            {
                findex = lindex - max + 1;
                if (findex < 0)
                {
                    findex = 0;
                }
            }
            m_hScalePixel = hScalePixel;
            if (m_showCrossLine)
            {
                float sX = m_targetOldX2;
                findex = m_crossStopIndex;
                while (sX >= m_leftVScaleWidth + m_hScalePixel / 2)
                {
                    findex = findex - 1;
                    m_offsetX = (float)(sX - m_leftVScaleWidth - m_hScalePixel / 2);
                    sX = (float)(sX - m_hScalePixel);
                }
                findex = findex + 1;
            }
            m_firstVisibleIndex = findex;
            m_lastVisibleIndex = lindex;
            checkChartLastVisibleIndex();
            calculateChartMaxMin();
        }
    }
}
